Bug 1395102 - P1 - Introduce a intermediate helper class to reuse code for upgrading origin directories; r=janv
authorTom Tung <shes050117@gmail.com>
Thu, 18 Oct 2018 11:12:28 +0200
changeset 490620 0d01e0a4de9550efec739bfe912b0cdb50057941
parent 490619 d15bcd82f19dfbd4e3a088b5b041cd8fe8c2a73a
child 490621 a0de0c0ec6b01e9d74cd2bcfe6333e1cbaf566dc
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersjanv
bugs1395102
milestone64.0a1
Bug 1395102 - P1 - Introduce a intermediate helper class to reuse code for upgrading origin directories; r=janv This patch mainly create a new helper class and it inherits from StorageDirectoraryHelper to reuse the code in CreateOrUpgradeDirectoryMetadataHelper::CreateOrUpgradeMetadataFiles(), UpgradeStorageFrom0_0To1_0Helper::DoUpgrade(), UpgradeStorageFrom1_0To2_0Helper::DoUpgrade(), UpgradeStorageFrom2_0To2_1Helper::DoUpgrade().
dom/quota/ActorsParent.cpp
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -1796,103 +1796,121 @@ private:
 
   void
   HandleToken(const nsDependentCSubstring& aToken);
 
   void
   HandleTrailingSeparator();
 };
 
+class UpgradeOriginDirectoriesHelper
+  : public StorageDirectoryHelper
+{
+public:
+  UpgradeOriginDirectoriesHelper(nsIFile* aDirectory,
+                                 bool aPersistent)
+    : StorageDirectoryHelper(aDirectory, aPersistent)
+  { }
+
+  nsresult
+  DoUpgrade();
+
+protected:
+  virtual ~UpgradeOriginDirectoriesHelper()
+  { }
+
+private:
+  virtual nsresult
+  PrepareOriginDirectory(OriginProps& aOriginProps, bool* aRemoved) = 0;
+};
+
 class CreateOrUpgradeDirectoryMetadataHelper final
-  : public StorageDirectoryHelper
+  : public UpgradeOriginDirectoriesHelper
 {
   nsCOMPtr<nsIFile> mPermanentStorageDir;
 
 public:
   CreateOrUpgradeDirectoryMetadataHelper(nsIFile* aDirectory,
                                          bool aPersistent)
-    : StorageDirectoryHelper(aDirectory, aPersistent)
+    : UpgradeOriginDirectoriesHelper(aDirectory, aPersistent)
   { }
 
-  nsresult
-  CreateOrUpgradeMetadataFiles();
-
 private:
   nsresult
   MaybeUpgradeOriginDirectory(nsIFile* aDirectory);
 
   nsresult
+  PrepareOriginDirectory(OriginProps& aOriginProps, bool* aRemoved) override;
+
+  nsresult
   ProcessOriginDirectory(const OriginProps& aOriginProps) override;
 };
 
 class UpgradeStorageFrom0_0To1_0Helper final
-  : public StorageDirectoryHelper
+  : public UpgradeOriginDirectoriesHelper
 {
 public:
   UpgradeStorageFrom0_0To1_0Helper(nsIFile* aDirectory,
                                    bool aPersistent)
-    : StorageDirectoryHelper(aDirectory, aPersistent)
+    : UpgradeOriginDirectoriesHelper(aDirectory, aPersistent)
   { }
 
-  nsresult
-  DoUpgrade();
-
 private:
   nsresult
+  PrepareOriginDirectory(OriginProps& aOriginProps, bool* aRemoved) override;
+
+  nsresult
   ProcessOriginDirectory(const OriginProps& aOriginProps) override;
 };
 
 class UpgradeStorageFrom1_0To2_0Helper final
-  : public StorageDirectoryHelper
+  : public UpgradeOriginDirectoriesHelper
 {
 public:
   UpgradeStorageFrom1_0To2_0Helper(nsIFile* aDirectory,
                                    bool aPersistent)
-    : StorageDirectoryHelper(aDirectory, aPersistent)
+    : UpgradeOriginDirectoriesHelper(aDirectory, aPersistent)
   { }
 
-  nsresult
-  DoUpgrade();
-
 private:
   nsresult
   MaybeUpgradeClients(const OriginProps& aOriginProps);
 
   nsresult
   MaybeRemoveAppsData(const OriginProps& aOriginProps,
                       bool* aRemoved);
 
   nsresult
   MaybeStripObsoleteOriginAttributes(const OriginProps& aOriginProps,
                                      bool* aStripped);
 
   nsresult
+  PrepareOriginDirectory(OriginProps& aOriginProps, bool* aRemoved) override;
+
+  nsresult
   ProcessOriginDirectory(const OriginProps& aOriginProps) override;
 };
 
-// XXXtt: The following class is duplicated from
-// UpgradeStorageFrom1_0To2_0Helper and it should be extracted out in
-// bug 1395102.
 class UpgradeStorageFrom2_0To2_1Helper final
-  : public StorageDirectoryHelper
+  : public UpgradeOriginDirectoriesHelper
 {
 public:
   UpgradeStorageFrom2_0To2_1Helper(nsIFile* aDirectory,
                                    bool aPersistent)
-    : StorageDirectoryHelper(aDirectory, aPersistent)
+    : UpgradeOriginDirectoriesHelper(aDirectory, aPersistent)
   { }
 
-  nsresult
-  DoUpgrade();
-
 private:
   nsresult
   MaybeUpgradeClients(const OriginProps& aOriginProps);
 
   nsresult
+  PrepareOriginDirectory(OriginProps& aOriginProps, bool* aRemoved) override;
+
+  nsresult
   ProcessOriginDirectory(const OriginProps& aOriginProps) override;
 };
 
 class RestoreDirectoryMetadata2Helper final
   : public StorageDirectoryHelper
 {
 public:
   RestoreDirectoryMetadata2Helper(nsIFile* aDirectory,
@@ -4461,17 +4479,17 @@ QuotaManager::MaybeUpgradePersistentStor
     return NS_OK;
   }
 
   // Create real metadata files for origin directories in persistent storage.
   RefPtr<CreateOrUpgradeDirectoryMetadataHelper> helper =
     new CreateOrUpgradeDirectoryMetadataHelper(persistentStorageDir,
                                                /* aPersistent */ true);
 
-  rv = helper->CreateOrUpgradeMetadataFiles();
+  rv = helper->DoUpgrade();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Upgrade metadata files for origin directories in temporary storage.
   nsCOMPtr<nsIFile> temporaryStorageDir;
   rv = NS_NewLocalFile(mTemporaryStoragePath, false,
                        getter_AddRefs(temporaryStorageDir));
@@ -4494,17 +4512,17 @@ QuotaManager::MaybeUpgradePersistentStor
       NS_WARNING("temporary entry is not a directory!");
       return NS_OK;
     }
 
     helper =
       new CreateOrUpgradeDirectoryMetadataHelper(temporaryStorageDir,
                                                  /* aPersistent */ false);
 
-    rv = helper->CreateOrUpgradeMetadataFiles();
+    rv = helper->DoUpgrade();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   // And finally rename persistent to default.
   rv = persistentStorageDir->RenameTo(nullptr, NS_LITERAL_STRING(DEFAULT_DIRECTORY_NAME));
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -4594,16 +4612,26 @@ QuotaManager::UpgradeStorageFrom0_0To1_0
   for (const PersistenceType persistenceType : kAllPersistenceTypes) {
     nsCOMPtr<nsIFile> directory;
     rv = NS_NewLocalFile(GetStoragePath(persistenceType), false,
                          getter_AddRefs(directory));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
+    bool exists;
+    rv = directory->Exists(&exists);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!exists) {
+      continue;
+    }
+
     bool persistent = persistenceType == PERSISTENCE_TYPE_PERSISTENT;
     RefPtr<UpgradeStorageFrom0_0To1_0Helper> helper =
       new UpgradeStorageFrom0_0To1_0Helper(directory, persistent);
 
     rv = helper->DoUpgrade();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -5730,16 +5758,18 @@ QuotaManager::GetInfoForChrome(nsACStrin
     ChromeOrigin(*aOrigin);
   }
 }
 
 // static
 bool
 QuotaManager::IsOriginInternal(const nsACString& aOrigin)
 {
+  MOZ_ASSERT(!aOrigin.IsEmpty());
+
   // The first prompt is not required for these origins.
   if (aOrigin.EqualsLiteral(kChromeOrigin) ||
       StringBeginsWith(aOrigin, nsDependentCString(kAboutHomeOriginPrefix)) ||
       StringBeginsWith(aOrigin, nsDependentCString(kIndexedDBOriginPrefix)) ||
       StringBeginsWith(aOrigin, nsDependentCString(kResourceOriginPrefix))) {
     return true;
   }
 
@@ -8381,20 +8411,32 @@ OriginProps::Init(nsIFile* aDirectory)
 
   nsString leafName;
   nsresult rv = aDirectory->GetLeafName(leafName);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (leafName.EqualsLiteral(kChromeOrigin)) {
+    // XXX We can remove this special handling once origin parser supports it
+    //     directly.
     mDirectory = aDirectory;
     mLeafName = leafName;
     mSpec = kChromeOrigin;
     mType = eChrome;
+  } else if (leafName.EqualsLiteral("moz-safe-about+++home")) {
+    // XXX We can remove this special handling once origin parser supports it
+    //     directly.
+
+    // This directory was accidentally created by a buggy nightly and can be
+    // safely removed.
+
+    mDirectory = aDirectory;
+    mLeafName = leafName;
+    mType = eObsolete;
   } else {
     nsCString spec;
     OriginAttributes attrs;
     OriginParser::ResultType result =
       OriginParser::ParseOrigin(NS_ConvertUTF16toUTF8(leafName), spec, &attrs);
     if (NS_WARN_IF(result == OriginParser::InvalidOrigin)) {
       return NS_ERROR_FAILURE;
     }
@@ -8788,106 +8830,76 @@ OriginParser::HandleTrailingSeparator()
   MOZ_ASSERT(mSchemeType == eFile);
 
   mPathnameComponents.AppendElement(EmptyCString());
 
   mState = eHandledTrailingSeparator;
 }
 
 nsresult
-CreateOrUpgradeDirectoryMetadataHelper::CreateOrUpgradeMetadataFiles()
+UpgradeOriginDirectoriesHelper::DoUpgrade()
 {
   AssertIsOnIOThread();
 
-  bool exists;
-  nsresult rv = mDirectory->Exists(&exists);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (!exists) {
-    return NS_OK;
-  }
+  DebugOnly<bool> exists;
+  MOZ_ASSERT(NS_SUCCEEDED(mDirectory->Exists(&exists)));
+  MOZ_ASSERT(exists);
 
   nsCOMPtr<nsIDirectoryEnumerator> entries;
-  rv = mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIFile> originDir;
-  while (NS_SUCCEEDED((rv = entries->GetNextFile(getter_AddRefs(originDir)))) &&
-         originDir) {
-    nsString leafName;
-    rv = originDir->GetLeafName(leafName);
+  nsresult rv = mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  while (true) {
+    nsCOMPtr<nsIFile> originDir;
+    rv = entries->GetNextFile(getter_AddRefs(originDir));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
+    if (!originDir) {
+      break;
+    }
+
     bool isDirectory;
     rv = originDir->IsDirectory(&isDirectory);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    if (isDirectory) {
-      if (leafName.EqualsLiteral("moz-safe-about+++home")) {
-        // This directory was accidentally created by a buggy nightly and can
-        // be safely removed.
-
-        QM_WARNING("Deleting accidental moz-safe-about+++home directory!");
-
-        rv = originDir->Remove(/* aRecursive */ true);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
-
-        continue;
+    if (!isDirectory) {
+      nsString leafName;
+      rv = originDir->GetLeafName(leafName);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
       }
-    } else {
+
       // Unknown files during upgrade are allowed. Just warn if we find them.
       if (!IsOSMetadata(leafName)) {
         UNKNOWN_FILE_WARNING(leafName);
       }
       continue;
     }
 
-    if (mPersistent) {
-      rv = MaybeUpgradeOriginDirectory(originDir);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-    }
-
     OriginProps originProps;
     rv = originProps.Init(originDir);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    if (!mPersistent) {
-      int64_t timestamp;
-      nsCString group;
-      nsCString origin;
-      Nullable<bool> isApp;
-      rv = GetDirectoryMetadata(originDir,
-                                timestamp,
-                                group,
-                                origin,
-                                isApp);
-      if (NS_FAILED(rv)) {
-        originProps.mTimestamp = GetLastModifiedTime(originDir, mPersistent);
-        originProps.mNeedsRestore = true;
-      } else if (!isApp.IsNull()) {
-        originProps.mIgnore = true;
+    if (originProps.mType != OriginProps::eObsolete) {
+      bool removed;
+      rv = PrepareOriginDirectory(originProps, &removed);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
       }
-    }
-    else {
-      bool persistent = QuotaManager::IsOriginInternal(originProps.mSpec);
-      originProps.mTimestamp = GetLastModifiedTime(originDir, persistent);
+      if (removed) {
+        continue;
+      }
     }
 
     mOriginProps.AppendElement(std::move(originProps));
   }
 
   if (mOriginProps.IsEmpty()) {
     return NS_OK;
   }
@@ -8993,16 +9005,59 @@ CreateOrUpgradeDirectoryMetadataHelper::
       return rv;
     }
   }
 
   return NS_OK;
 }
 
 nsresult
+CreateOrUpgradeDirectoryMetadataHelper::PrepareOriginDirectory(
+                                                      OriginProps& aOriginProps,
+                                                      bool* aRemoved)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(aOriginProps.mDirectory);
+  MOZ_ASSERT(aRemoved);
+
+  nsresult rv;
+
+  if (mPersistent) {
+    rv = MaybeUpgradeOriginDirectory(aOriginProps.mDirectory);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    bool persistent = QuotaManager::IsOriginInternal(aOriginProps.mSpec);
+    aOriginProps.mTimestamp =
+      GetLastModifiedTime(aOriginProps.mDirectory, persistent);
+  } else {
+    int64_t timestamp;
+    nsCString group;
+    nsCString origin;
+    Nullable<bool> isApp;
+    rv = GetDirectoryMetadata(aOriginProps.mDirectory,
+                              timestamp,
+                              group,
+                              origin,
+                              isApp);
+    if (NS_FAILED(rv)) {
+      aOriginProps.mTimestamp =
+        GetLastModifiedTime(aOriginProps.mDirectory, mPersistent);
+      aOriginProps.mNeedsRestore = true;
+    } else if (!isApp.IsNull()) {
+      aOriginProps.mIgnore = true;
+    }
+  }
+
+  *aRemoved = false;
+  return NS_OK;
+}
+
+nsresult
 CreateOrUpgradeDirectoryMetadataHelper::ProcessOriginDirectory(
                                                 const OriginProps& aOriginProps)
 {
   AssertIsOnIOThread();
 
   nsresult rv;
 
   if (mPersistent) {
@@ -9102,93 +9157,42 @@ CreateOrUpgradeDirectoryMetadataHelper::
       return rv;
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-UpgradeStorageFrom0_0To1_0Helper::DoUpgrade()
+UpgradeStorageFrom0_0To1_0Helper::PrepareOriginDirectory(
+                                                      OriginProps& aOriginProps,
+                                                      bool* aRemoved)
 {
   AssertIsOnIOThread();
-
-  bool exists;
-  nsresult rv = mDirectory->Exists(&exists);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (!exists) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIDirectoryEnumerator> entries;
-  rv = mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIFile> originDir;
-  while (NS_SUCCEEDED((rv = entries->GetNextFile(getter_AddRefs(originDir)))) &&
-         originDir) {
-    bool isDirectory;
-    rv = originDir->IsDirectory(&isDirectory);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (!isDirectory) {
-      nsString leafName;
-      rv = originDir->GetLeafName(leafName);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-
-      // Unknown files during upgrade are allowed. Just warn if we find them.
-      if (!IsOSMetadata(leafName)) {
-        UNKNOWN_FILE_WARNING(leafName);
-      }
-      continue;
-    }
-
-    OriginProps originProps;
-    rv = originProps.Init(originDir);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    int64_t timestamp;
-    nsCString group;
-    nsCString origin;
-    Nullable<bool> isApp;
-    nsresult rv = GetDirectoryMetadata(originDir,
-                                       timestamp,
-                                       group,
-                                       origin,
-                                       isApp);
-    if (NS_FAILED(rv) || isApp.IsNull()) {
-      originProps.mTimestamp = GetLastModifiedTime(originDir, mPersistent);
-      originProps.mNeedsRestore = true;
-    } else {
-      originProps.mTimestamp = timestamp;
-    }
-
-    mOriginProps.AppendElement(std::move(originProps));
-  }
-
-  if (mOriginProps.IsEmpty()) {
-    return NS_OK;
-  }
-
-  rv = ProcessOriginDirectories();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
+  MOZ_ASSERT(aOriginProps.mDirectory);
+  MOZ_ASSERT(aRemoved);
+
+  int64_t timestamp;
+  nsCString group;
+  nsCString origin;
+  Nullable<bool> isApp;
+  nsresult rv = GetDirectoryMetadata(aOriginProps.mDirectory,
+                                     timestamp,
+                                     group,
+                                     origin,
+                                     isApp);
+  if (NS_FAILED(rv) || isApp.IsNull()) {
+    aOriginProps.mTimestamp =
+      GetLastModifiedTime(aOriginProps.mDirectory, mPersistent);
+    aOriginProps.mNeedsRestore = true;
+  } else {
+    aOriginProps.mTimestamp = timestamp;
+  }
+
+  *aRemoved = false;
   return NS_OK;
 }
 
 nsresult
 UpgradeStorageFrom0_0To1_0Helper::ProcessOriginDirectory(
                                                 const OriginProps& aOriginProps)
 {
   AssertIsOnIOThread();
@@ -9233,118 +9237,16 @@ UpgradeStorageFrom0_0To1_0Helper::Proces
       return rv;
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-UpgradeStorageFrom1_0To2_0Helper::DoUpgrade()
-{
-  AssertIsOnIOThread();
-
-  DebugOnly<bool> exists;
-  MOZ_ASSERT(NS_SUCCEEDED(mDirectory->Exists(&exists)));
-  MOZ_ASSERT(exists);
-
-  nsCOMPtr<nsIDirectoryEnumerator> entries;
-  nsresult rv = mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIFile> originDir;
-  while (NS_SUCCEEDED((rv = entries->GetNextFile(getter_AddRefs(originDir)))) && originDir) {
-    bool isDirectory;
-    rv = originDir->IsDirectory(&isDirectory);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (!isDirectory) {
-      nsString leafName;
-      rv = originDir->GetLeafName(leafName);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-
-      // Unknown files during upgrade are allowed. Just warn if we find them.
-      if (!IsOSMetadata(leafName)) {
-        UNKNOWN_FILE_WARNING(leafName);
-      }
-      continue;
-    }
-
-    OriginProps originProps;
-    rv = originProps.Init(originDir);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    rv = MaybeUpgradeClients(originProps);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    bool removed;
-    rv = MaybeRemoveAppsData(originProps, &removed);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-    if (removed) {
-      continue;
-    }
-
-    int64_t timestamp;
-    nsCString group;
-    nsCString origin;
-    Nullable<bool> isApp;
-    nsresult rv = GetDirectoryMetadata(originDir,
-                                       timestamp,
-                                       group,
-                                       origin,
-                                       isApp);
-    if (NS_FAILED(rv) || isApp.IsNull()) {
-      originProps.mNeedsRestore = true;
-    }
-
-    nsCString suffix;
-    rv = GetDirectoryMetadata2(originDir,
-                               timestamp,
-                               suffix,
-                               group,
-                               origin,
-                               isApp.SetValue());
-    if (NS_FAILED(rv)) {
-      originProps.mTimestamp = GetLastModifiedTime(originDir, mPersistent);
-      originProps.mNeedsRestore2 = true;
-    } else {
-      originProps.mTimestamp = timestamp;
-    }
-
-    mOriginProps.AppendElement(std::move(originProps));
-  }
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (mOriginProps.IsEmpty()) {
-    return NS_OK;
-  }
-
-  rv = ProcessOriginDirectories();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-nsresult
 UpgradeStorageFrom1_0To2_0Helper::MaybeUpgradeClients(
                                                 const OriginProps& aOriginProps)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aOriginProps.mDirectory);
 
   QuotaManager* quotaManager = QuotaManager::Get();
   MOZ_ASSERT(quotaManager);
@@ -9510,16 +9412,72 @@ UpgradeStorageFrom1_0To2_0Helper::MaybeS
     return rv;
   }
 
   *aStripped = true;
   return NS_OK;
 }
 
 nsresult
+UpgradeStorageFrom1_0To2_0Helper::PrepareOriginDirectory(
+                                                      OriginProps& aOriginProps,
+                                                      bool* aRemoved)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(aOriginProps.mDirectory);
+  MOZ_ASSERT(aRemoved);
+
+  nsresult rv = MaybeUpgradeClients(aOriginProps);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  bool removed;
+  rv = MaybeRemoveAppsData(aOriginProps, &removed);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  if (removed) {
+    *aRemoved = true;
+    return NS_OK;
+  }
+
+  int64_t timestamp;
+  nsCString group;
+  nsCString origin;
+  Nullable<bool> isApp;
+  rv = GetDirectoryMetadata(aOriginProps.mDirectory,
+                            timestamp,
+                            group,
+                            origin,
+                            isApp);
+  if (NS_FAILED(rv) || isApp.IsNull()) {
+    aOriginProps.mNeedsRestore = true;
+  }
+
+  nsCString suffix;
+  rv = GetDirectoryMetadata2(aOriginProps.mDirectory,
+                             timestamp,
+                             suffix,
+                             group,
+                             origin,
+                             isApp.SetValue());
+  if (NS_FAILED(rv)) {
+    aOriginProps.mTimestamp =
+      GetLastModifiedTime(aOriginProps.mDirectory, mPersistent);
+    aOriginProps.mNeedsRestore2 = true;
+  } else {
+    aOriginProps.mTimestamp = timestamp;
+  }
+
+  *aRemoved = false;
+  return NS_OK;
+}
+
+nsresult
 UpgradeStorageFrom1_0To2_0Helper::ProcessOriginDirectory(
                                                 const OriginProps& aOriginProps)
 {
   AssertIsOnIOThread();
 
   bool stripped;
   nsresult rv = MaybeStripObsoleteOriginAttributes(aOriginProps, &stripped);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -9551,110 +9509,16 @@ UpgradeStorageFrom1_0To2_0Helper::Proces
       return rv;
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-UpgradeStorageFrom2_0To2_1Helper::DoUpgrade()
-{
-  AssertIsOnIOThread();
-
-  DebugOnly<bool> exists;
-  MOZ_ASSERT(NS_SUCCEEDED(mDirectory->Exists(&exists)));
-  MOZ_ASSERT(exists);
-
-  nsCOMPtr<nsIDirectoryEnumerator> entries;
-  nsresult rv = mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIFile> originDir;
-  while (NS_SUCCEEDED((rv = entries->GetNextFile(getter_AddRefs(originDir)))) && originDir) {
-    bool isDirectory;
-    rv = originDir->IsDirectory(&isDirectory);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (!isDirectory) {
-      nsString leafName;
-      rv = originDir->GetLeafName(leafName);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-
-      // Unknown files during upgrade are allowed. Just warn if we find them.
-      if (!IsOSMetadata(leafName)) {
-        UNKNOWN_FILE_WARNING(leafName);
-      }
-      continue;
-    }
-
-    OriginProps originProps;
-    rv = originProps.Init(originDir);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    // Only update DOM Cache directory for adding padding file.
-    rv = MaybeUpgradeClients(originProps);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    int64_t timestamp;
-    nsCString group;
-    nsCString origin;
-    Nullable<bool> isApp;
-    nsresult rv = GetDirectoryMetadata(originDir,
-                                       timestamp,
-                                       group,
-                                       origin,
-                                       isApp);
-    if (NS_FAILED(rv) || isApp.IsNull()) {
-      originProps.mNeedsRestore = true;
-    }
-
-    nsCString suffix;
-    rv = GetDirectoryMetadata2(originDir,
-                               timestamp,
-                               suffix,
-                               group,
-                               origin,
-                               isApp.SetValue());
-    if (NS_FAILED(rv)) {
-      originProps.mTimestamp = GetLastModifiedTime(originDir, mPersistent);
-      originProps.mNeedsRestore2 = true;
-    } else {
-      originProps.mTimestamp = timestamp;
-    }
-
-    mOriginProps.AppendElement(std::move(originProps));
-  }
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (mOriginProps.IsEmpty()) {
-    return NS_OK;
-  }
-
-  rv = ProcessOriginDirectories();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-nsresult
 UpgradeStorageFrom2_0To2_1Helper::MaybeUpgradeClients(
                                                 const OriginProps& aOriginProps)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aOriginProps.mDirectory);
 
   QuotaManager* quotaManager = QuotaManager::Get();
   MOZ_ASSERT(quotaManager);
@@ -9707,16 +9571,62 @@ UpgradeStorageFrom2_0To2_1Helper::MaybeU
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult
+UpgradeStorageFrom2_0To2_1Helper::PrepareOriginDirectory(
+                                                      OriginProps& aOriginProps,
+                                                      bool* aRemoved)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(aOriginProps.mDirectory);
+  MOZ_ASSERT(aRemoved);
+
+  nsresult rv = MaybeUpgradeClients(aOriginProps);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  int64_t timestamp;
+  nsCString group;
+  nsCString origin;
+  Nullable<bool> isApp;
+  rv = GetDirectoryMetadata(aOriginProps.mDirectory,
+                            timestamp,
+                            group,
+                            origin,
+                            isApp);
+  if (NS_FAILED(rv) || isApp.IsNull()) {
+    aOriginProps.mNeedsRestore = true;
+  }
+
+  nsCString suffix;
+  rv = GetDirectoryMetadata2(aOriginProps.mDirectory,
+                             timestamp,
+                             suffix,
+                             group,
+                             origin,
+                             isApp.SetValue());
+  if (NS_FAILED(rv)) {
+    aOriginProps.mTimestamp =
+      GetLastModifiedTime(aOriginProps.mDirectory, mPersistent);
+    aOriginProps.mNeedsRestore2 = true;
+  } else {
+    aOriginProps.mTimestamp = timestamp;
+  }
+
+  *aRemoved = false;
+  return NS_OK;
+}
+
+nsresult
 UpgradeStorageFrom2_0To2_1Helper::ProcessOriginDirectory(
                                                 const OriginProps& aOriginProps)
 {
   AssertIsOnIOThread();
 
   nsresult rv;
 
   if (aOriginProps.mNeedsRestore) {