Bug 1115496 - [DeviceStorage] Use change event to notify gaia if there is default location change. r=dhylands
authorAlphan Chen <alchen@mozilla.com>
Mon, 30 Mar 2015 10:48:41 +0800
changeset 236513 f4108e07d92682ae98a2782c62db053d8098abb7
parent 236512 e99e4351d407e38a815309391e99cde3aa88b9ab
child 236514 0ac8ff6c3bedd74a69cb3507fde5393e8717d961
push id28511
push userkwierso@gmail.com
push dateTue, 31 Mar 2015 02:34:53 +0000
treeherdermozilla-central@8af276ab8636 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdhylands
bugs1115496
milestone39.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 1115496 - [DeviceStorage] Use change event to notify gaia if there is default location change. r=dhylands
dom/devicestorage/DeviceStorage.h
dom/devicestorage/nsDeviceStorage.cpp
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -329,16 +329,18 @@ private:
                                                   nsAString& aOutStoragePath);
   already_AddRefed<nsDOMDeviceStorage>
     GetStorageByName(const nsAString &aStorageName);
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
   bool mIsWatchingFile;
   bool mAllowedToWatchFile;
+  bool mIsDefaultLocation;
+  void DispatchDefaultChangeEvent();
 
   nsresult Notify(const char* aReason, class DeviceStorageFile* aFile);
 
   friend class WatchFileEvent;
   friend class DeviceStorageRequest;
 
   static mozilla::StaticAutoPtr<nsTArray<nsString>> sVolumeNameCache;
 
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -71,16 +71,17 @@
 #include "nsIVolumeService.h"
 #endif
 
 #define DEVICESTORAGE_PROPERTIES \
   "chrome://global/content/devicestorage.properties"
 #define DEFAULT_THREAD_TIMEOUT_MS 30000
 #define PREF_STORAGE_WRITABLE_NAME \
   "device.storage.writable.name"
+#define STORAGE_CHANGE_EVENT "change"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::ipc;
 
 #include "nsDirectoryServiceDefs.h"
 
@@ -3361,16 +3362,18 @@ nsDOMDeviceStorage::Init(nsPIDOMWindow* 
 
   MOZ_ASSERT(aWindow);
 
   SetRootDirectoryForType(aType, aVolName);
   if (!mRootDirectory) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if (!mStorageName.IsEmpty()) {
+    Preferences::AddStrongObserver(this, PREF_STORAGE_WRITABLE_NAME);
+    mIsDefaultLocation = Default();
     RegisterForSDCardChanges(this);
 
 #ifdef MOZ_WIDGET_GONK
     if (DeviceStorageTypeChecker::IsVolumeBased(mStorageType)) {
       nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
       if (NS_WARN_IF(!vs)) {
         return NS_ERROR_FAILURE;
       }
@@ -3434,16 +3437,17 @@ nsDOMDeviceStorage::Shutdown()
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mFileSystem) {
     mFileSystem->Shutdown();
     mFileSystem = nullptr;
   }
 
   if (!mStorageName.IsEmpty()) {
+    Preferences::RemoveObserver(this, PREF_STORAGE_WRITABLE_NAME);
     UnregisterForSDCardChanges(this);
   }
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   obs->RemoveObserver(this, kFileWatcherUpdate);
   obs->RemoveObserver(this, "disk-space-watcher");
 }
 
@@ -4325,16 +4329,44 @@ nsDOMDeviceStorage::EnumerateInternal(co
     return cursor.forget();
   }
 
   nsContentPermissionUtils::AskPermission(r, win);
 
   return cursor.forget();
 }
 
+void
+nsDOMDeviceStorage::DispatchDefaultChangeEvent()
+{
+  nsAdoptingString DefaultLocation;
+  GetDefaultStorageName(mStorageType, DefaultLocation);
+
+  DeviceStorageChangeEventInit init;
+  init.mBubbles = true;
+  init.mCancelable = false;
+  init.mPath = DefaultLocation;
+
+  if (mIsDefaultLocation) {
+    init.mReason.AssignLiteral("default-location-changed");
+  } else {
+    init.mReason.AssignLiteral("became-default-location");
+  }
+
+  nsRefPtr<DeviceStorageChangeEvent> event =
+    DeviceStorageChangeEvent::Constructor(this,
+                                          NS_LITERAL_STRING(STORAGE_CHANGE_EVENT),
+                                          init);
+  event->SetTrusted(true);
+
+  bool ignore;
+  DispatchEvent(event, &ignore);
+  mIsDefaultLocation = Default();
+}
+
 #ifdef MOZ_WIDGET_GONK
 void
 nsDOMDeviceStorage::DispatchStatusChangeEvent(nsAString& aStatus)
 {
   if (aStatus == mLastStatus) {
     // We've already sent this status, don't bother sending it again.
     return;
   }
@@ -4342,17 +4374,18 @@ nsDOMDeviceStorage::DispatchStatusChange
 
   DeviceStorageChangeEventInit init;
   init.mBubbles = true;
   init.mCancelable = false;
   init.mPath = mStorageName;
   init.mReason = aStatus;
 
   nsRefPtr<DeviceStorageChangeEvent> event =
-    DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("change"),
+    DeviceStorageChangeEvent::Constructor(this,
+                                          NS_LITERAL_STRING(STORAGE_CHANGE_EVENT),
                                           init);
   event->SetTrusted(true);
 
   bool ignore;
   DispatchEvent(event, &ignore);
 }
 
 void
@@ -4403,16 +4436,24 @@ nsDOMDeviceStorage::Observe(nsISupports 
     if (!NS_strcmp(aData, MOZ_UTF16("full"))) {
       Notify("low-disk-space", file);
     } else if (!NS_strcmp(aData, MOZ_UTF16("free"))) {
       Notify("available-disk-space", file);
     }
     return NS_OK;
   }
 
+  if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) &&
+               aData &&
+               nsDependentString(aData).Equals(NS_LITERAL_STRING(PREF_STORAGE_WRITABLE_NAME)))
+  {
+    DispatchDefaultChangeEvent();
+    return NS_OK;
+  }
+
 #ifdef MOZ_WIDGET_GONK
   else if (!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
     // We invalidate the used space cache for the volume that actually changed
     // state.
     nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
     if (!vol) {
       return NS_OK;
     }
@@ -4460,17 +4501,18 @@ nsDOMDeviceStorage::Notify(const char* a
 
   DeviceStorageChangeEventInit init;
   init.mBubbles = true;
   init.mCancelable = false;
   aFile->GetFullPath(init.mPath);
   init.mReason.AssignWithConversion(aReason);
 
   nsRefPtr<DeviceStorageChangeEvent> event =
-    DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("change"),
+    DeviceStorageChangeEvent::Constructor(this,
+                                          NS_LITERAL_STRING(STORAGE_CHANGE_EVENT),
                                           init);
   event->SetTrusted(true);
 
   bool ignore;
   DispatchEvent(event, &ignore);
   return NS_OK;
 }