Client.cpp (6683B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "Client.h" 8 9 // Global includes 10 #include "mozilla/Assertions.h" 11 #include "mozilla/dom/quota/QuotaManager.h" 12 #include "mozilla/ipc/BackgroundParent.h" 13 14 namespace mozilla::dom::quota { 15 16 using mozilla::ipc::AssertIsOnBackgroundThread; 17 using mozilla::ipc::IsOnBackgroundThread; 18 19 namespace { 20 21 const char kIDBPrefix = 'I'; 22 const char kDOMCachePrefix = 'C'; 23 const char kSDBPrefix = 'S'; 24 const char kFILESYSTEMPrefix = 'F'; 25 const char kLSPrefix = 'L'; 26 27 template <Client::Type type> 28 struct ClientTypeTraits; 29 30 template <> 31 struct ClientTypeTraits<Client::Type::IDB> { 32 template <typename T> 33 static void To(T& aData) { 34 aData.AssignLiteral(IDB_DIRECTORY_NAME); 35 } 36 37 static void To(char& aData) { aData = kIDBPrefix; } 38 39 template <typename T> 40 static bool From(const T& aData) { 41 return aData.EqualsLiteral(IDB_DIRECTORY_NAME); 42 } 43 44 static bool From(char aData) { return aData == kIDBPrefix; } 45 }; 46 47 template <> 48 struct ClientTypeTraits<Client::Type::DOMCACHE> { 49 template <typename T> 50 static void To(T& aData) { 51 aData.AssignLiteral(DOMCACHE_DIRECTORY_NAME); 52 } 53 54 static void To(char& aData) { aData = kDOMCachePrefix; } 55 56 template <typename T> 57 static bool From(const T& aData) { 58 return aData.EqualsLiteral(DOMCACHE_DIRECTORY_NAME); 59 } 60 61 static bool From(char aData) { return aData == kDOMCachePrefix; } 62 }; 63 64 template <> 65 struct ClientTypeTraits<Client::Type::SDB> { 66 template <typename T> 67 static void To(T& aData) { 68 aData.AssignLiteral(SDB_DIRECTORY_NAME); 69 } 70 71 static void To(char& aData) { aData = kSDBPrefix; } 72 73 template <typename T> 74 static bool From(const T& aData) { 75 return aData.EqualsLiteral(SDB_DIRECTORY_NAME); 76 } 77 78 static bool From(char aData) { return aData == kSDBPrefix; } 79 }; 80 81 template <> 82 struct ClientTypeTraits<Client::Type::FILESYSTEM> { 83 template <typename T> 84 static void To(T& aData) { 85 aData.AssignLiteral(FILESYSTEM_DIRECTORY_NAME); 86 } 87 88 static void To(char& aData) { aData = kFILESYSTEMPrefix; } 89 90 template <typename T> 91 static bool From(const T& aData) { 92 return aData.EqualsLiteral(FILESYSTEM_DIRECTORY_NAME); 93 } 94 95 static bool From(char aData) { return aData == kFILESYSTEMPrefix; } 96 }; 97 98 template <> 99 struct ClientTypeTraits<Client::Type::LS> { 100 template <typename T> 101 static void To(T& aData) { 102 aData.AssignLiteral(LS_DIRECTORY_NAME); 103 } 104 105 static void To(char& aData) { aData = kLSPrefix; } 106 107 template <typename T> 108 static bool From(const T& aData) { 109 return aData.EqualsLiteral(LS_DIRECTORY_NAME); 110 } 111 112 static bool From(char aData) { return aData == kLSPrefix; } 113 }; 114 115 template <typename T> 116 bool TypeTo_impl(Client::Type aType, T& aData) { 117 switch (aType) { 118 case Client::IDB: 119 ClientTypeTraits<Client::Type::IDB>::To(aData); 120 return true; 121 122 case Client::DOMCACHE: 123 ClientTypeTraits<Client::Type::DOMCACHE>::To(aData); 124 return true; 125 126 case Client::SDB: 127 ClientTypeTraits<Client::Type::SDB>::To(aData); 128 return true; 129 130 case Client::FILESYSTEM: 131 ClientTypeTraits<Client::Type::FILESYSTEM>::To(aData); 132 return true; 133 134 case Client::LS: 135 if (CachedNextGenLocalStorageEnabled()) { 136 ClientTypeTraits<Client::Type::LS>::To(aData); 137 return true; 138 } 139 [[fallthrough]]; 140 141 case Client::TYPE_MAX: 142 default: 143 return false; 144 } 145 146 MOZ_CRASH("Should never get here!"); 147 } 148 149 template <typename T> 150 bool TypeFrom_impl(const T& aData, Client::Type& aType) { 151 if (ClientTypeTraits<Client::Type::IDB>::From(aData)) { 152 aType = Client::IDB; 153 return true; 154 } 155 156 if (ClientTypeTraits<Client::Type::DOMCACHE>::From(aData)) { 157 aType = Client::DOMCACHE; 158 return true; 159 } 160 161 if (ClientTypeTraits<Client::Type::SDB>::From(aData)) { 162 aType = Client::SDB; 163 return true; 164 } 165 166 if (ClientTypeTraits<Client::Type::FILESYSTEM>::From(aData)) { 167 aType = Client::FILESYSTEM; 168 return true; 169 } 170 171 if (CachedNextGenLocalStorageEnabled() && 172 ClientTypeTraits<Client::Type::LS>::From(aData)) { 173 aType = Client::LS; 174 return true; 175 } 176 177 return false; 178 } 179 180 void BadType() { MOZ_CRASH("Bad client type value!"); } 181 182 } // namespace 183 184 // static 185 bool Client::IsValidType(Type aType) { 186 switch (aType) { 187 case Client::IDB: 188 case Client::DOMCACHE: 189 case Client::SDB: 190 case Client::FILESYSTEM: 191 return true; 192 193 case Client::LS: 194 if (CachedNextGenLocalStorageEnabled()) { 195 return true; 196 } 197 [[fallthrough]]; 198 199 default: 200 return false; 201 } 202 } 203 204 // static 205 bool Client::TypeToText(Type aType, nsAString& aText, const fallible_t&) { 206 nsString text; 207 if (!TypeTo_impl(aType, text)) { 208 return false; 209 } 210 aText = text; 211 return true; 212 } 213 214 // static 215 nsAutoString Client::TypeToString(Type aType) { 216 nsAutoString res; 217 if (!TypeTo_impl(aType, res)) { 218 BadType(); 219 } 220 return res; 221 } 222 223 // static 224 nsAutoCString Client::TypeToText(Type aType) { 225 nsAutoCString res; 226 if (!TypeTo_impl(aType, res)) { 227 BadType(); 228 } 229 return res; 230 } 231 232 // static 233 bool Client::TypeFromText(const nsAString& aText, Type& aType, 234 const fallible_t&) { 235 Type type; 236 if (!TypeFrom_impl(aText, type)) { 237 return false; 238 } 239 aType = type; 240 return true; 241 } 242 243 // static 244 Client::Type Client::TypeFromText(const nsACString& aText) { 245 Type type; 246 if (!TypeFrom_impl(aText, type)) { 247 BadType(); 248 } 249 return type; 250 } 251 252 // static 253 char Client::TypeToPrefix(Type aType) { 254 char prefix; 255 if (!TypeTo_impl(aType, prefix)) { 256 BadType(); 257 } 258 return prefix; 259 } 260 261 // static 262 bool Client::TypeFromPrefix(char aPrefix, Type& aType, const fallible_t&) { 263 Type type; 264 if (!TypeFrom_impl(aPrefix, type)) { 265 return false; 266 } 267 aType = type; 268 return true; 269 } 270 271 bool Client::InitiateShutdownWorkThreads() { 272 AssertIsOnBackgroundThread(); 273 274 QuotaManager::MaybeRecordQuotaClientShutdownStep(GetType(), "starting"_ns); 275 276 InitiateShutdown(); 277 278 return IsShutdownCompleted(); 279 } 280 281 void Client::FinalizeShutdownWorkThreads() { 282 QuotaManager::MaybeRecordQuotaClientShutdownStep(GetType(), "completed"_ns); 283 284 FinalizeShutdown(); 285 } 286 287 // static 288 bool Client::IsShuttingDownOnBackgroundThread() { 289 MOZ_ASSERT(IsOnBackgroundThread()); 290 return QuotaManager::IsShuttingDown(); 291 } 292 293 // static 294 bool Client::IsShuttingDownOnNonBackgroundThread() { 295 MOZ_ASSERT(!IsOnBackgroundThread()); 296 return QuotaManager::IsShuttingDown(); 297 } 298 299 } // namespace mozilla::dom::quota