Add support for a "split" incognito behavior for extensions.
- On by default for apps, off by default for extensions.
- Split mode means "run incognito extensions in a separate process if the user
says OK, and the two processes can only see their own profile."
- Spanning mode is what we have now, and means "run a single extension process,
but allow it to access both profiles if the user says OK."

BUG=49232
BUG=49114
TEST=extensions still work in incognito when you check "Allow in Incognito".

Review URL: http://codereview.chromium.org/3210007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58033 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 362ef224..7ba0f42 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -204,7 +204,7 @@
   registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
                  NotificationService::AllSources());
   registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED,
-                 Source<Profile>(profile_));
+                 NotificationService::AllSources());
   prefs->AddPrefObserver(prefs::kExtensionInstallAllowList, this);
   prefs->AddPrefObserver(prefs::kExtensionInstallDenyList, this);
 
@@ -1368,7 +1368,8 @@
     }
 
     case NotificationType::EXTENSION_PROCESS_TERMINATED: {
-      DCHECK_EQ(profile_, Source<Profile>(source).ptr());
+      if (profile_ != Source<Profile>(source).ptr()->GetOriginalProfile())
+        break;
 
       ExtensionHost* host = Details<ExtensionHost>(details).ptr();
 
@@ -1387,7 +1388,11 @@
 
       // Unload the entire extension. We want it to be in a consistent state:
       // either fully working or not loaded at all, but never half-crashed.
-      UnloadExtension(host->extension()->id());
+      // We do it in a PostTask so that other handlers of this notification will
+      // still have access to the Extension and ExtensionHost.
+      MessageLoop::current()->PostTask(FROM_HERE,
+          NewRunnableMethod(this, &ExtensionsService::UnloadExtension,
+                            host->extension()->id()));
       break;
     }