Bug 1232506: Make dom/devicestorage really work with e10s. r=alchen
authorDave Hylands <dhylands@mozilla.com>
Fri, 18 Dec 2015 17:17:46 -0800
changeset 278148 471e252b7b301c81051efb6f16e1d1c964711408
parent 278147 4bbe608d70f0934642031662a228364d0ef3feb3
child 278149 75129f6ee55773f5f4436285e7ccfb5e096b9bab
push id69692
push userdhylands@mozilla.com
push dateFri, 01 Jan 2016 00:02:05 +0000
treeherdermozilla-inbound@471e252b7b30 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersalchen
bugs1232506
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1232506: Make dom/devicestorage really work with e10s. r=alchen
dom/devicestorage/DeviceStorageStatics.cpp
dom/devicestorage/DeviceStorageStatics.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
--- a/dom/devicestorage/DeviceStorageStatics.cpp
+++ b/dom/devicestorage/DeviceStorageStatics.cpp
@@ -126,16 +126,40 @@ DeviceStorageStatics::Init()
 
 void
 DeviceStorageStatics::InitDirs()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sMutex.AssertCurrentThreadOwns();
   DS_LOG_INFO("");
 
+#if !defined(MOZ_WIDGET_GONK)
+  if (!XRE_IsParentProcess()) {
+    // For gonk, we have the parent process forward the directory information
+    // to the child using ContentParent::ForwardKnownInfo. On desktop, this
+    // winds up slowing down the startup (in particular ts_paint), so rather
+    // than penalize all e10s processes, we do a synchronous IPC call here,
+    // which only penalizes child processes which actually use DeviceStorage.
+
+    dom::ContentChild* child = dom::ContentChild::GetSingleton();
+    DeviceStorageLocationInfo locationInfo;
+    child->SendGetDeviceStorageLocations(&locationInfo);
+
+    NS_NewLocalFile(locationInfo.apps(),     true, getter_AddRefs(sInstance->mDirs[TYPE_APPS]));
+    NS_NewLocalFile(locationInfo.crashes(),  true, getter_AddRefs(sInstance->mDirs[TYPE_CRASHES]));
+    NS_NewLocalFile(locationInfo.pictures(), true, getter_AddRefs(sInstance->mDirs[TYPE_PICTURES]));
+    NS_NewLocalFile(locationInfo.videos(),   true, getter_AddRefs(sInstance->mDirs[TYPE_VIDEOS]));
+    NS_NewLocalFile(locationInfo.music(),    true, getter_AddRefs(sInstance->mDirs[TYPE_MUSIC]));
+    NS_NewLocalFile(locationInfo.sdcard(),   true, getter_AddRefs(sInstance->mDirs[TYPE_SDCARD]));
+
+    sInstance->mInitialized = true;
+    return;
+  }
+#endif
+
   nsCOMPtr<nsIProperties> dirService
     = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
   MOZ_ASSERT(dirService);
 
 #if !defined(MOZ_WIDGET_GONK)
 
 // Keep MOZ_WIDGET_COCOA above XP_UNIX,
 // because both are defined in Darwin builds.
@@ -266,25 +290,32 @@ DeviceStorageStatics::DumpDirs()
     "pictures",
     "videos",
     "music",
     "sdcard",
     "override",
     nullptr
   };
 
+  const char* ptStr;
+  if (XRE_IsParentProcess()) {
+    ptStr = "parent";
+  } else {
+    ptStr = "child";
+  }
+
   for (uint32_t i = 0; i < TYPE_COUNT; ++i) {
     MOZ_ASSERT(storageTypes[i]);
 
     nsString path;
     if (mDirs[i]) {
       mDirs[i]->GetPath(path);
     }
-    DS_LOG_INFO("%s: '%s'",
-      storageTypes[i], NS_LossyConvertUTF16toASCII(path).get());
+    DS_LOG_INFO("(%s) %s: '%s'",
+      ptStr, storageTypes[i], NS_LossyConvertUTF16toASCII(path).get());
   }
 #endif
 }
 
 void
 DeviceStorageStatics::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -292,16 +323,33 @@ DeviceStorageStatics::Shutdown()
   DS_LOG_INFO("");
 
   Preferences::RemoveObserver(this, kPrefOverrideRootDir);
   Preferences::RemoveObserver(this, kPrefTesting);
   Preferences::RemoveObserver(this, kPrefPromptTesting);
   Preferences::RemoveObserver(this, kPrefWritableName);
 }
 
+/* static */ void
+DeviceStorageStatics::GetDeviceStorageLocationsForIPC(
+  DeviceStorageLocationInfo* aLocationInfo)
+{
+  MOZ_ASSERT(XRE_IsParentProcess());
+  MOZ_ASSERT(NS_IsMainThread());
+
+  InitializeDirs();
+
+  GetDirPath(TYPE_APPS,     aLocationInfo->apps());
+  GetDirPath(TYPE_CRASHES,  aLocationInfo->crashes());
+  GetDirPath(TYPE_PICTURES, aLocationInfo->pictures());
+  GetDirPath(TYPE_VIDEOS,   aLocationInfo->videos());
+  GetDirPath(TYPE_MUSIC,    aLocationInfo->music());
+  GetDirPath(TYPE_SDCARD,   aLocationInfo->sdcard());
+}
+
 /* static */ already_AddRefed<nsIFile>
 DeviceStorageStatics::GetDir(DeviceStorageType aType)
 {
   MOZ_ASSERT(aType < TYPE_COUNT);
 
   StaticMutexAutoLock lock(sMutex);
   if (NS_WARN_IF(!sInstance)) {
     return nullptr;
@@ -327,16 +375,26 @@ DeviceStorageStatics::GetDir(DeviceStora
 #ifdef MOZ_WIDGET_GONK
     /* We should use volume mount points on B2G. */
     MOZ_ASSERT(!file);
 #endif
   }
   return file.forget();
 }
 
+/* static */ void
+DeviceStorageStatics::GetDirPath(DeviceStorageType aType, nsString& aDirPath)
+{
+  aDirPath.Truncate();
+  nsCOMPtr<nsIFile> file = GetDir(aType);
+  if (file) {
+    file->GetPath(aDirPath);
+  }
+}
+
 /* static */ bool
 DeviceStorageStatics::HasOverrideRootDir()
 {
   StaticMutexAutoLock lock(sMutex);
   if (NS_WARN_IF(!sInstance)) {
     return false;
   }
   return sInstance->mDirs[TYPE_OVERRIDE];
--- a/dom/devicestorage/DeviceStorageStatics.h
+++ b/dom/devicestorage/DeviceStorageStatics.h
@@ -3,17 +3,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_devicestorage_DeviceStorageStatics_h
 #define mozilla_dom_devicestorage_DeviceStorageStatics_h
 
 #include "mozilla/Mutex.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/StaticPtr.h"
+#include "nsArrayUtils.h"
 
+class nsString;
 class nsDOMDeviceStorage;
 class DeviceStorageFile;
 #ifdef MOZ_WIDGET_GONK
 class nsIVolume;
 #endif
 
 namespace mozilla {
 namespace dom {
@@ -30,16 +35,18 @@ public:
   static void AddListener(nsDOMDeviceStorage* aListener);
   static void RemoveListener(nsDOMDeviceStorage* aListener);
 
   static bool LowDiskSpace();
   static bool IsPromptTesting();
   static void GetWritableName(nsString& aName);
   static void SetWritableName(const nsAString& aName);
 
+  static void GetDeviceStorageLocationsForIPC(DeviceStorageLocationInfo* aLocationInfo);
+
   static bool HasOverrideRootDir();
   static already_AddRefed<nsIFile> GetAppsDir();
   static already_AddRefed<nsIFile> GetCrashesDir();
   static already_AddRefed<nsIFile> GetPicturesDir();
   static already_AddRefed<nsIFile> GetVideosDir();
   static already_AddRefed<nsIFile> GetMusicDir();
   static already_AddRefed<nsIFile> GetSdcardDir();
 
@@ -51,16 +58,17 @@ private:
     TYPE_VIDEOS,
     TYPE_MUSIC,
     TYPE_SDCARD,
     TYPE_OVERRIDE,
     TYPE_COUNT
   };
 
   static already_AddRefed<nsIFile> GetDir(DeviceStorageType aType);
+  static void GetDirPath(DeviceStorageType aType, nsString& aString);
 
   DeviceStorageStatics();
   virtual ~DeviceStorageStatics();
 
   void Init();
   void InitDirs();
   void DumpDirs();
   void Shutdown();
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -25,16 +25,17 @@
 
 #include <set>
 
 #include "mozilla/a11y/PDocAccessible.h"
 #include "AppProcessChecker.h"
 #include "AudioChannelService.h"
 #include "BlobParent.h"
 #include "CrashReporterParent.h"
+#include "DeviceStorageStatics.h"
 #include "GMPServiceParent.h"
 #include "HandlerServiceParent.h"
 #include "IHistory.h"
 #include "imgIContainer.h"
 #include "mozIApplication.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/CSSStyleSheet.h"
 #include "mozilla/DataStorage.h"
@@ -5776,16 +5777,23 @@ ContentParent::RecvGetDeviceStorageLocat
   mozilla::AndroidBridge::GetExternalPublicDirectory(aType, *aPath);
   return true;
 #else
   return false;
 #endif
 }
 
 bool
+ContentParent::RecvGetDeviceStorageLocations(DeviceStorageLocationInfo* info)
+{
+    DeviceStorageStatics::GetDeviceStorageLocationsForIPC(info);
+    return true;
+}
+
+bool
 ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo)
 {
 #ifdef MOZ_WIDGET_ANDROID
   nsSystemInfo::GetAndroidSystemInfo(aInfo);
   return true;
 #else
   MOZ_CRASH("wrong platform!");
   return false;
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -943,16 +943,18 @@ private:
     virtual bool RecvGamepadListenerRemoved() override;
     virtual bool RecvProfile(const nsCString& aProfile) override;
     virtual bool RecvGetGraphicsDeviceInitData(DeviceInitData* aOut) override;
     void StartProfiler(nsIProfilerStartParams* aParams);
 
     virtual bool RecvGetDeviceStorageLocation(const nsString& aType,
                                               nsString* aPath) override;
 
+    virtual bool RecvGetDeviceStorageLocations(DeviceStorageLocationInfo* info) override;
+
     virtual bool RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo) override;
 
     // If you add strong pointers to cycle collected objects here, be sure to
     // release these objects in ShutDownProcess.  See the comment there for more
     // details.
 
     GeckoChildProcessHost* mSubprocess;
     ContentParent* mOpener;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -214,16 +214,25 @@ union DeviceStorageParams
   DeviceStorageUsedSpaceParams;
   DeviceStorageAvailableParams;
   DeviceStorageStatusParams;
   DeviceStorageFormatParams;
   DeviceStorageMountParams;
   DeviceStorageUnmountParams;
 };
 
+struct DeviceStorageLocationInfo {
+  nsString music;
+  nsString pictures;
+  nsString videos;
+  nsString sdcard;
+  nsString apps;
+  nsString crashes;
+};
+
 struct FMRadioRequestEnableParams
 {
   double frequency;
 };
 
 struct FMRadioRequestDisableParams
 {
 
@@ -1158,16 +1167,19 @@ parent:
       returns (nsresult rv,
                bool windowOpened,
                FrameScriptInfo[] frameScripts,
                nsCString urlToLoad);
 
     sync GetDeviceStorageLocation(nsString type)
         returns (nsString path);
 
+    sync GetDeviceStorageLocations()
+	returns (DeviceStorageLocationInfo info);
+
     sync GetAndroidSystemInfo()
         returns (AndroidSystemInfo info);
 
     /**
      * Tells the parent to ungrab the pointer on the default display.
      *
      * This is for GTK platforms where we have to ensure the pointer ungrab happens in the
      * chrome process as that's the process that receives the pointer event.