Bug 968215 - SettingsService needs to have a callback when transaction are completed. r=bent
authorSam Joch <samuel@guiora.com>
Fri, 07 Feb 2014 12:19:58 +0100
changeset 168967 b53ca595416891ccac061d9e88522a171341f38c
parent 168966 f646b79cf1e056160619d2f9d987bc91783c829d
child 168968 1f21bc9fc654ac60d3698d21db9ffaa49be06a7d
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbent
bugs968215
milestone30.0a1
Bug 968215 - SettingsService needs to have a callback when transaction are completed. r=bent
dom/bluetooth/BluetoothService.cpp
dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
dom/bluetooth/bluez/BluetoothHfpManager.cpp
dom/fmradio/FMRadioService.cpp
dom/interfaces/settings/nsISettingsService.idl
dom/settings/SettingsService.js
dom/src/geolocation/nsGeolocation.cpp
dom/system/gonk/AudioManager.cpp
dom/system/gonk/AutoMounterSetting.cpp
dom/system/gonk/GonkGPSGeolocationProvider.cpp
dom/system/gonk/TimeZoneSettingObserver.cpp
--- a/dom/bluetooth/BluetoothService.cpp
+++ b/dom/bluetooth/BluetoothService.cpp
@@ -560,17 +560,17 @@ BluetoothService::HandleStartup()
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!sToggleInProgress);
 
   nsCOMPtr<nsISettingsService> settings =
     do_GetService("@mozilla.org/settingsService;1");
   NS_ENSURE_TRUE(settings, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsISettingsServiceLock> settingsLock;
-  nsresult rv = settings->CreateLock(getter_AddRefs(settingsLock));
+  nsresult rv = settings->CreateLock(nullptr, getter_AddRefs(settingsLock));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<StartupTask> callback = new StartupTask();
   rv = settingsLock->Get(BLUETOOTH_ENABLED_SETTING, callback);
   NS_ENSURE_SUCCESS(rv, rv);
 
   sToggleInProgress = true;
   return NS_OK;
--- a/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
@@ -398,17 +398,17 @@ BluetoothHfpManager::Init()
   mListener = new BluetoothRilListener();
   NS_ENSURE_TRUE(mListener->Listen(true), false);
 
   nsCOMPtr<nsISettingsService> settings =
     do_GetService("@mozilla.org/settingsService;1");
   NS_ENSURE_TRUE(settings, false);
 
   nsCOMPtr<nsISettingsServiceLock> settingsLock;
-  nsresult rv = settings->CreateLock(getter_AddRefs(settingsLock));
+  nsresult rv = settings->CreateLock(nullptr, getter_AddRefs(settingsLock));
   NS_ENSURE_SUCCESS(rv, false);
 
   nsRefPtr<GetVolumeTask> callback = new GetVolumeTask();
   rv = settingsLock->Get(AUDIO_VOLUME_BT_SCO_ID, callback);
   NS_ENSURE_SUCCESS(rv, false);
 
   return true;
 }
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -428,17 +428,17 @@ BluetoothHfpManager::Init()
   }
 #endif
 
   nsCOMPtr<nsISettingsService> settings =
     do_GetService("@mozilla.org/settingsService;1");
   NS_ENSURE_TRUE(settings, false);
 
   nsCOMPtr<nsISettingsServiceLock> settingsLock;
-  nsresult rv = settings->CreateLock(getter_AddRefs(settingsLock));
+  nsresult rv = settings->CreateLock(nullptr, getter_AddRefs(settingsLock));
   NS_ENSURE_SUCCESS(rv, false);
 
   nsRefPtr<GetVolumeTask> callback = new GetVolumeTask();
   rv = settingsLock->Get(AUDIO_VOLUME_BT_SCO_ID, callback);
   NS_ENSURE_SUCCESS(rv, false);
 
   Listen();
 
--- a/dom/fmradio/FMRadioService.cpp
+++ b/dom/fmradio/FMRadioService.cpp
@@ -422,17 +422,17 @@ FMRadioService::Enable(double aFrequency
   // Cache the frequency value, and set it after the FM radio HW is enabled
   mPendingFrequencyInKHz = roundedFrequency;
 
   if (!mHasReadRilSetting) {
     nsCOMPtr<nsISettingsService> settings =
       do_GetService("@mozilla.org/settingsService;1");
 
     nsCOMPtr<nsISettingsServiceLock> settingsLock;
-    nsresult rv = settings->CreateLock(getter_AddRefs(settingsLock));
+    nsresult rv = settings->CreateLock(nullptr, getter_AddRefs(settingsLock));
     if (NS_FAILED(rv)) {
       TransitionState(ErrorResponse(
         NS_LITERAL_STRING("Can't create settings lock")), Disabled);
       return;
     }
 
     nsRefPtr<ReadRilSettingTask> callback =
       new ReadRilSettingTask(mPendingRequest);
--- a/dom/interfaces/settings/nsISettingsService.idl
+++ b/dom/interfaces/settings/nsISettingsService.idl
@@ -6,24 +6,31 @@
 
 [scriptable, uuid(aad47850-2e87-11e2-81c1-0800200c9a66)]
 interface nsISettingsServiceCallback : nsISupports
 {
   void handle(in DOMString aName, in jsval aResult);
   void handleError(in DOMString aErrorMessage);
 };
 
+[scriptable, uuid(f1b3d820-8e75-11e3-baa8-0800200c9a66)]
+interface nsISettingsTransactionCompleteCallback : nsISupports
+{
+  void handle();
+  void handleAbort(in DOMString aErrorMessage);
+};
+
 [scriptable, uuid(d7a395a0-e292-11e1-834e-1761d57f5f99)]
 interface nsISettingsServiceLock : nsISupports
 {
   void set(in string aName,
            in jsval aValue,
            in nsISettingsServiceCallback aCallback,
            [optional] in string aMessage);
 
   void get(in string aName, in nsISettingsServiceCallback aCallback);
 };
 
-[scriptable, uuid(f656f0c0-f776-11e1-a21f-0800200c9a66)]
+[scriptable, uuid(0505acf0-8e76-11e3-baa8-0800200c9a66)]
 interface nsISettingsService : nsISupports
 {
-  nsISettingsServiceLock createLock();
+  nsISettingsServiceLock createLock([optional] in nsISettingsTransactionCompleteCallback aCallback);
 };
--- a/dom/settings/SettingsService.js
+++ b/dom/settings/SettingsService.js
@@ -127,22 +127,32 @@ SettingsServiceLock.prototype = {
           }.bind(lock);
           getReq.onerror = function error(event) { callback ? callback.handleError(event.target.errorMessage) : null; };
           break;
       }
     }
     lock._open = true;
   },
 
-  createTransactionAndProcess: function() {
+  createTransactionAndProcess: function(aCallback) {
     if (this._settingsService._settingsDB._db) {
       let lock;
       while (lock = this._settingsService._locks.dequeue()) {
         if (!lock._transaction) {
           lock._transaction = lock._settingsService._settingsDB._db.transaction(SETTINGSSTORE_NAME, "readwrite");
+          if (aCallback) {
+            lock._transaction.oncomplete = aCallback.handle;
+            lock._transaction.onabort = function(event) {
+              let message = '';
+              if (event.target.error) {
+                message = event.target.error.name + ': ' + event.target.error.message;
+              }
+              aCallback.handleAbort(message);
+            };
+          }
         }
         if (!lock._isBusy) {
           lock.process();
         } else {
           this._settingsService._locks.enqueue(lock);
           return;
         }
       }
@@ -194,21 +204,21 @@ SettingsService.prototype = {
 
   nextTick: function nextTick(aCallback, thisObj) {
     if (thisObj)
       aCallback = aCallback.bind(thisObj);
 
     Services.tm.currentThread.dispatch(aCallback, Ci.nsIThread.DISPATCH_NORMAL);
   },
 
-  createLock: function createLock() {
+  createLock: function createLock(aCallback) {
     var lock = new SettingsServiceLock(this);
     this._locks.enqueue(lock);
     this._settingsDB.ensureDB(
-      function() { lock.createTransactionAndProcess(); },
+      function() { lock.createTransactionAndProcess(aCallback); },
       function() { dump("SettingsService failed to open DB!\n"); }
     );
     this.nextTick(function() { this._open = false; }, lock);
     return lock;
   },
 
   classID : SETTINGSSERVICE_CID,
   QueryInterface : XPCOMUtils.generateQI([Ci.nsISettingsService]),
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -641,17 +641,17 @@ nsresult nsGeolocationService::Init()
   }
 
   // check if the geolocation service is enable from settings
   nsCOMPtr<nsISettingsService> settings =
     do_GetService("@mozilla.org/settingsService;1");
 
   if (settings) {
     nsCOMPtr<nsISettingsServiceLock> settingsLock;
-    nsresult rv = settings->CreateLock(getter_AddRefs(settingsLock));
+    nsresult rv = settings->CreateLock(nullptr, getter_AddRefs(settingsLock));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsRefPtr<GeolocationSettingsCallback> callback = new GeolocationSettingsCallback();
     rv = settingsLock->Get(GEO_SETINGS_ENABLED, callback);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     // If we cannot obtain the settings service, we continue
     // assuming that the geolocation is enabled:
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -392,17 +392,17 @@ AudioManager::AudioManager()
   SetStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE,
                        sMaxStreamVolumeTbl[AUDIO_STREAM_ENFORCED_AUDIBLE]);
 
   // Get the initial volume index from settings DB during boot up.
   nsCOMPtr<nsISettingsService> settingsService =
     do_GetService("@mozilla.org/settingsService;1");
   NS_ENSURE_TRUE_VOID(settingsService);
   nsCOMPtr<nsISettingsServiceLock> lock;
-  nsresult rv = settingsService->CreateLock(getter_AddRefs(lock));
+  nsresult rv = settingsService->CreateLock(nullptr, getter_AddRefs(lock));
   NS_ENSURE_SUCCESS_VOID(rv);
   nsCOMPtr<nsISettingsServiceCallback> callback = new AudioChannelVolInitCallback();
   NS_ENSURE_TRUE_VOID(callback);
   lock->Get("audio.volume.content", callback);
   lock->Get("audio.volume.notification", callback);
   lock->Get("audio.volume.alarm", callback);
   lock->Get("audio.volume.telephony", callback);
   lock->Get("audio.volume.bt_sco", callback);
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -112,17 +112,17 @@ AutoMounterSetting::AutoMounterSetting()
   // becomes unlocked and changes ums.mode appropriately.
   nsCOMPtr<nsISettingsService> settingsService =
     do_GetService("@mozilla.org/settingsService;1");
   if (!settingsService) {
     ERR("Failed to get settingsLock service!");
     return;
   }
   nsCOMPtr<nsISettingsServiceLock> lock;
-  settingsService->CreateLock(getter_AddRefs(lock));
+  settingsService->CreateLock(nullptr, getter_AddRefs(lock));
   nsCOMPtr<nsISettingsServiceCallback> callback = new SettingsServiceCallback();
   mozilla::AutoSafeJSContext cx;
   JS::Rooted<JS::Value> value(cx);
   value.setInt32(AUTOMOUNTER_DISABLE);
   lock->Set(UMS_MODE, value, callback, nullptr);
   value.setInt32(mStatus);
   lock->Set(UMS_STATUS, value, nullptr, nullptr);
 }
@@ -157,17 +157,17 @@ public:
 
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
     nsCOMPtr<nsISettingsService> settingsService =
       do_GetService("@mozilla.org/settingsService;1");
     NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
     nsCOMPtr<nsISettingsServiceLock> lock;
-    settingsService->CreateLock(getter_AddRefs(lock));
+    settingsService->CreateLock(nullptr, getter_AddRefs(lock));
     nsCOMPtr<nsISettingsServiceCallback> callback =
       new CheckVolumeSettingsCallback(mVolumeName);
     nsPrintfCString setting(UMS_VOLUME_ENABLED_PREFIX "%s" UMS_VOLUME_ENABLED_SUFFIX,
                             mVolumeName.get());
     lock->Get(setting.get(), callback);
     return NS_OK;
   }
 
@@ -189,17 +189,17 @@ public:
 
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
     nsCOMPtr<nsISettingsService> settingsService =
       do_GetService("@mozilla.org/settingsService;1");
     NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
     nsCOMPtr<nsISettingsServiceLock> lock;
-    settingsService->CreateLock(getter_AddRefs(lock));
+    settingsService->CreateLock(nullptr, getter_AddRefs(lock));
     // lock may be null if this gets called during shutdown.
     if (lock) {
       mozilla::AutoSafeJSContext cx;
       JS::Rooted<JS::Value> value(cx, JS::Int32Value(mStatus));
       lock->Set(UMS_STATUS, value, nullptr, nullptr);
     }
     return NS_OK;
   }
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -378,17 +378,17 @@ GonkGPSGeolocationProvider::RequestSetti
 {
   MOZ_ASSERT(aKey);
   nsCOMPtr<nsISettingsService> ss = do_GetService("@mozilla.org/settingsService;1");
   if (!ss) {
     MOZ_ASSERT(ss);
     return;
   }
   nsCOMPtr<nsISettingsServiceLock> lock;
-  ss->CreateLock(getter_AddRefs(lock));
+  ss->CreateLock(nullptr, getter_AddRefs(lock));
   lock->Get(aKey, this);
 }
 
 void
 GonkGPSGeolocationProvider::RequestDataConnection()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
--- a/dom/system/gonk/TimeZoneSettingObserver.cpp
+++ b/dom/system/gonk/TimeZoneSettingObserver.cpp
@@ -84,17 +84,17 @@ public:
       // Set the settings based on the current system timezone.
       nsCOMPtr<nsISettingsServiceLock> lock;
       nsCOMPtr<nsISettingsService> settingsService =
         do_GetService("@mozilla.org/settingsService;1");
       if (!settingsService) {
         ERR("Failed to get settingsLock service!");
         return NS_OK;
       }
-      settingsService->CreateLock(getter_AddRefs(lock));
+      settingsService->CreateLock(nullptr, getter_AddRefs(lock));
       JS::Rooted<JS::Value> value(cx, JS::StringValue(jsStr));
       lock->Set(TIME_TIMEZONE, value, nullptr, nullptr);
       return NS_OK;
     }
 
     // Set the system timezone based on the current settings.
     if (aResult.isString()) {
       return TimeZoneSettingObserver::SetTimeZone(aResult, cx);
@@ -130,17 +130,17 @@ TimeZoneSettingObserver::TimeZoneSetting
   // value at boot time. The handle() will be called after reading.
   nsCOMPtr<nsISettingsServiceLock> lock;
   nsCOMPtr<nsISettingsService> settingsService =
     do_GetService("@mozilla.org/settingsService;1");
   if (!settingsService) {
     ERR("Failed to get settingsLock service!");
     return;
   }
-  settingsService->CreateLock(getter_AddRefs(lock));
+  settingsService->CreateLock(nullptr, getter_AddRefs(lock));
   nsCOMPtr<nsISettingsServiceCallback> callback = new TimeZoneSettingCb();
   lock->Get(TIME_TIMEZONE, callback);
 }
 
 nsresult TimeZoneSettingObserver::SetTimeZone(const JS::Value &aValue, JSContext *aContext)
 {
   // Convert the JS value to a nsCString type.
   // The value should be a JS string like "America/Chicago" or "UTC-05:00".