Shutdown StoragePartition before ProfileIOData is being shut down

- Expose a new ShutdownStoragePartitions method on BrowserContext
- Calls the new method in the subclasses of BrowserContext before actual
  destruction / shutdown starts

Content modules that are hung on StoragePartition often try to dereference
ResourceContext (which is owned by ProfileIOData in chromium cases) even after
ResourceContext is destroyed, so it could easily lead to U-A-F.  This happens
because StoragePartitions are destroyed in BrowserContext's dtor, while
ProfileIOData and any other objects that are managed/owned by BrowserContext's
subclasses are usually destroyed earlier than that (i.e. their destructors run
before the base class's one).

This change tries to add a new explicit method,
BrowserContext::ShutdownStoragePartitions, and let embedders call it before
the embedders are going to destroy/shutdown their own objects (which include
ResourceContext), so that content modules can safely assume they can
dereference those objects while its StoragePartition's still there.

BUG=529896

Review-Url: https://codereview.chromium.org/2159133002
Cr-Commit-Position: refs/heads/master@{#407781}
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index 729df89..59b0047 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -486,10 +486,18 @@
       << "Attempting to destroy a BrowserContext that never called "
       << "Initialize()";
 
+  DCHECK(!GetUserData(kStoragePartitionMapKeyName))
+      << "StoragePartitionMap is not shut down properly";
+
   RemoveBrowserContextFromUserIdMap(this);
 
   if (GetUserData(kDownloadManagerKeyName))
     GetDownloadManager(this)->Shutdown();
 }
 
+void BrowserContext::ShutdownStoragePartitions() {
+  if (GetUserData(kStoragePartitionMapKeyName))
+    RemoveUserData(kStoragePartitionMapKeyName);
+}
+
 }  // namespace content