Keep a web_apps.extension_ids prefs-backed roster

Future commits will need it, as installing web apps from their URL will
need to know whether or not those web apps (and their underlying
extensions) are already installed.

Based on nigeltao's https://crrev.com/c/1179115

But rebased on top of latest CLs and added testing.

[email protected]

Bug: 876577
Change-Id: Ic3e837efe8fb2f79e30a2ffb044f6e02e988d20b
Reviewed-on: https://chromium-review.googlesource.com/1192462
Reviewed-by: Giovanni Ortuño Urquidi <[email protected]>
Reviewed-by: Dominick Ng <[email protected]>
Commit-Queue: Giovanni Ortuño Urquidi <[email protected]>
Cr-Commit-Position: refs/heads/master@{#586669}
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 9625318..109d09b7 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -61,6 +61,7 @@
 #include "chrome/browser/ui/webui/favicon_source.h"
 #include "chrome/browser/ui/webui/theme_source.h"
 #include "chrome/browser/upgrade_detector/upgrade_detector.h"
+#include "chrome/browser/web_applications/extensions/web_app_extension_ids_map.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/crash_keys.h"
@@ -146,6 +147,21 @@
       return;  // Yup, known extension, don't uninstall.
   }
 
+  // Historically, the code under //chrome/browser/extensions has
+  // unsurprisingly managed all extensions. Later, Progressive Web Apps (PWAs)
+  // were implemented on top of extensions, more out of convenience than out of
+  // principle. As of mid 2018, there is work underway to separate PWAs's
+  // implementation details from the //c/b/e code. During the transition
+  // period, PWA-extensions are no longer managed solely by //c/b/e code. We
+  // add a special case here so that //c/b/e code doesn't uninstall
+  // PWA-extensions that it doesn't otherwise know about.
+  //
+  // Long term, PWAs will be completely separate from extensions, and we can
+  // remove this cross-link.
+  if (web_app::ExtensionIdsMap::HasExtensionId(profile_->GetPrefs(), id)) {
+    return;
+  }
+
   // We get the list of external extensions to check from preferences.
   // It is possible that an extension has preferences but is not loaded.
   // For example, an extension that requires experimental permissions