Migrates legacy packaged app data when it's upgraded to a platform app

Currently, data stored by a legacy packaged app in the HTML5 filesystem
and IndexedDB is lost when it gets migrated to the new type of Chrome App
(internally referred to as "platform apps"). This is because Chrome stores
extension and legacy packaged app data in the general storage partition and
it stores platform app data in a it's own isolated storage partition.
When a legacy packaged app is upgraded to the new type of app, a new
isolated storage partition is created but the data gets left behind
in the general storage partition.

This change fixes this by performing a migration of the data to the new
storage partition at the time of the upgrade. It only migrates IndexedDB
and HTML5 filesystem because these are the only permanent data storage
options available to platform apps. Platform apps are prohibited from
using DOMStorage and WebSQL. Data stored by chrome.storage APIs is
separate from the storage partitions.

BUG=302577

Review URL: https://codereview.chromium.org/671873004

Cr-Commit-Position: refs/heads/master@{#313394}
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index a935947..98333c4 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/content_settings/content_settings_internal_extension_provider.h"
 #include "chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.h"
 #include "chrome/browser/extensions/api/content_settings/content_settings_service.h"
+#include "chrome/browser/extensions/app_data_migrator.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/data_deleter.h"
@@ -271,7 +272,8 @@
       installs_delayed_for_gc_(false),
       is_first_run_(false),
       block_extensions_(false),
-      shared_module_service_(new extensions::SharedModuleService(profile_)) {
+      shared_module_service_(new extensions::SharedModuleService(profile_)),
+      app_data_migrator_(new extensions::AppDataMigrator(profile_, registry_)) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   // Figure out if extension installation should be enabled.
@@ -1858,6 +1860,16 @@
   delayed_installs_.Remove(extension->id());
   if (InstallVerifier::NeedsVerification(*extension))
     system_->install_verifier()->VerifyExtension(extension->id());
+
+  const Extension* old = GetInstalledExtension(extension->id());
+  if (extensions::AppDataMigrator::NeedsMigration(old, extension)) {
+    app_data_migrator_->DoMigrationAndReply(
+        old, extension,
+        base::Bind(&ExtensionService::FinishInstallation, AsWeakPtr(),
+                   make_scoped_refptr(extension), was_ephemeral));
+    return;
+  }
+
   FinishInstallation(extension, was_ephemeral);
 }