diff --git a/mobile/android/base/GeckoEvent.java b/mobile/android/base/GeckoEvent.java index 1bd59a8e390..3ed9310ddb8 100644 --- a/mobile/android/base/GeckoEvent.java +++ b/mobile/android/base/GeckoEvent.java @@ -67,7 +67,10 @@ public class GeckoEvent { REMOVE_OBSERVER(34), LOW_MEMORY(35), NETWORK_LINK_CHANGE(36), - TELEMETRY_HISTOGRAM_ADD(37); + TELEMETRY_HISTOGRAM_ADD(37), + PREFERENCES_OBSERVE(39), + PREFERENCES_GET(40), + PREFERENCES_REMOVE_OBSERVERS(41); public final int value; @@ -186,6 +189,8 @@ public class GeckoEvent { private int mWidth; private int mHeight; + private String[] mPrefNames; + private GeckoEvent(NativeGeckoEvent event) { mType = event.value; } @@ -689,6 +694,26 @@ public class GeckoEvent { return event; } + public static GeckoEvent createPreferencesObserveEvent(int requestId, String[] prefNames) { + GeckoEvent event = new GeckoEvent(NativeGeckoEvent.PREFERENCES_OBSERVE); + event.mCount = requestId; + event.mPrefNames = prefNames; + return event; + } + + public static GeckoEvent createPreferencesGetEvent(int requestId, String[] prefNames) { + GeckoEvent event = new GeckoEvent(NativeGeckoEvent.PREFERENCES_GET); + event.mCount = requestId; + event.mPrefNames = prefNames; + return event; + } + + public static GeckoEvent createPreferencesRemoveObserversEvent(int requestId) { + GeckoEvent event = new GeckoEvent(NativeGeckoEvent.PREFERENCES_REMOVE_OBSERVERS); + event.mCount = requestId; + return event; + } + public static GeckoEvent createLowMemoryEvent(int level) { GeckoEvent event = new GeckoEvent(NativeGeckoEvent.LOW_MEMORY); event.mMetaState = level; diff --git a/mobile/android/base/PrefsHelper.java b/mobile/android/base/PrefsHelper.java index 2e5211c38ab..b3f97371af5 100644 --- a/mobile/android/base/PrefsHelper.java +++ b/mobile/android/base/PrefsHelper.java @@ -28,28 +28,18 @@ public final class PrefsHelper { private static int sUniqueRequestId = 1; public static int getPref(String prefName, PrefHandler callback) { - JSONArray prefs = new JSONArray(); - prefs.put(prefName); - return getPrefs(prefs, callback); + return getPrefsInternal(new String[] { prefName }, callback); } public static int getPrefs(String[] prefNames, PrefHandler callback) { - JSONArray prefs = new JSONArray(); - for (String p : prefNames) { - prefs.put(p); - } - return getPrefs(prefs, callback); + return getPrefsInternal(prefNames, callback); } public static int getPrefs(ArrayList prefNames, PrefHandler callback) { - JSONArray prefs = new JSONArray(); - for (String p : prefNames) { - prefs.put(p); - } - return getPrefs(prefs, callback); + return getPrefsInternal(prefNames.toArray(new String[prefNames.size()]), callback); } - public static int getPrefs(JSONArray prefNames, PrefHandler callback) { + private static int getPrefsInternal(String[] prefNames, PrefHandler callback) { int requestId; synchronized (PrefsHelper.class) { ensureRegistered(); @@ -59,25 +49,12 @@ public final class PrefsHelper { } GeckoEvent event; - try { - JSONObject message = new JSONObject(); - message.put("requestId", Integer.toString(requestId)); - message.put("preferences", prefNames); - event = GeckoEvent.createBroadcastEvent(callback.isObserver() ? - "Preferences:Observe" : "Preferences:Get", message.toString()); - GeckoAppShell.sendEventToGecko(event); - } catch (Exception e) { - Log.e(LOGTAG, "Error while composing Preferences:" + - (callback.isObserver() ? "Observe" : "Get") + " message", e); - - // if we failed to send the message, drop our reference to the callback because - // otherwise it will leak since we will never get the response - synchronized (PrefsHelper.class) { - sCallbacks.remove(requestId); - } - - return -1; + if (callback.isObserver()) { + event = GeckoEvent.createPreferencesObserveEvent(requestId, prefNames); + } else { + event = GeckoEvent.createPreferencesGetEvent(requestId, prefNames); } + GeckoAppShell.sendEventToGecko(event); return requestId; } diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 703ddd0101b..e673cb1fbbb 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -279,10 +279,7 @@ var BrowserApp = { Services.obs.addObserver(this, "Session:Stop", false); Services.obs.addObserver(this, "SaveAs:PDF", false); Services.obs.addObserver(this, "Browser:Quit", false); - Services.obs.addObserver(this, "Preferences:Get", false); Services.obs.addObserver(this, "Preferences:Set", false); - Services.obs.addObserver(this, "Preferences:Observe", false); - Services.obs.addObserver(this, "Preferences:RemoveObservers", false); Services.obs.addObserver(this, "ScrollTo:FocusedInput", false); Services.obs.addObserver(this, "Sanitize:ClearData", false); Services.obs.addObserver(this, "FullScreen:Exit", false); @@ -993,18 +990,10 @@ var BrowserApp = { notifyPrefObservers: function(aPref) { this._prefObservers[aPref].forEach(function(aRequestId) { - let request = { requestId : aRequestId, - preferences : [aPref] }; - this.getPreferences(request); + this.getPreferences(aRequestId, [aPref], 1); }, this); }, - getPreferences: function getPreferences(aPrefsRequest, aListen) { - this.handlePreferencesRequest(aPrefsRequest.requestId, - aPrefsRequest.preferences, - aListen); - }, - handlePreferencesRequest: function handlePreferencesRequest(aRequestId, aPrefNames, aListen) { @@ -1134,26 +1123,6 @@ var BrowserApp = { }); }, - removePreferenceObservers: function removePreferenceObservers(aRequestId) { - let newPrefObservers = []; - for (let prefName in this._prefObservers) { - let requestIds = this._prefObservers[prefName]; - // Remove the requestID from the preference handlers - let i = requestIds.indexOf(aRequestId); - if (i >= 0) { - requestIds.splice(i, 1); - } - - // If there are no more request IDs, remove the observer - if (requestIds.length == 0) { - Services.prefs.removeObserver(prefName, this); - } else { - newPrefObservers[prefName] = requestIds; - } - } - this._prefObservers = newPrefObservers; - }, - setPreferences: function setPreferences(aPref) { let json = JSON.parse(aPref); @@ -1452,22 +1421,10 @@ var BrowserApp = { this.saveAsPDF(browser); break; - case "Preferences:Get": - this.getPreferences(JSON.parse(aData)); - break; - case "Preferences:Set": this.setPreferences(aData); break; - case "Preferences:Observe": - this.getPreferences(JSON.parse(aData), true); - break; - - case "Preferences:RemoveObservers": - this.removePreferenceObservers(aData); - break; - case "ScrollTo:FocusedInput": // these messages come from a change in the viewable area and not user interaction // we allow scrolling to the selected input, but not zooming the page @@ -1541,6 +1498,34 @@ var BrowserApp = { return this.getTabForId(tabId); }, + getPreferences: function getPreferences(requestId, prefNames, count) { + this.handlePreferencesRequest(requestId, prefNames, false); + }, + + observePreferences: function observePreferences(requestId, prefNames, count) { + this.handlePreferencesRequest(requestId, prefNames, true); + }, + + removePreferenceObservers: function removePreferenceObservers(aRequestId) { + let newPrefObservers = []; + for (let prefName in this._prefObservers) { + let requestIds = this._prefObservers[prefName]; + // Remove the requestID from the preference handlers + let i = requestIds.indexOf(aRequestId); + if (i >= 0) { + requestIds.splice(i, 1); + } + + // If there are no more request IDs, remove the observer + if (requestIds.length == 0) { + Services.prefs.removeObserver(prefName, this); + } else { + newPrefObservers[prefName] = requestIds; + } + } + this._prefObservers = newPrefObservers; + }, + // This method will print a list from fromIndex to toIndex, optionally // selecting selIndex(if fromIndex<=selIndex<=toIndex) showHistory: function(fromIndex, toIndex, selIndex) { diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index fbf1f234c35..bca825aa46b 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -672,6 +672,11 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj) break; } + case PREFERENCES_REMOVE_OBSERVERS: { + mCount = jenv->GetIntField(jobj, jCountField); + break; + } + default: break; } diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index 9d29d48c562..bc9cfab4d45 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -738,6 +738,7 @@ public: ADD_OBSERVER = 38, PREFERENCES_OBSERVE = 39, PREFERENCES_GET = 40, + PREFERENCES_REMOVE_OBSERVERS = 41, dummy_java_enum_list_end }; diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index a4b2aa19233..a00caee0ee0 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -543,6 +543,27 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait) AddObserver(curEvent->Characters(), curEvent->Observer()); break; + case AndroidGeckoEvent::PREFERENCES_GET: + case AndroidGeckoEvent::PREFERENCES_OBSERVE: { + const nsTArray &prefNames = curEvent->PrefNames(); + size_t count = prefNames.Length(); + nsAutoArrayPtr prefNamePtrs(new const PRUnichar*[count]); + for (size_t i = 0; i < count; ++i) { + prefNamePtrs[i] = prefNames[i].get(); + } + + if (curEvent->Type() == AndroidGeckoEvent::PREFERENCES_GET) { + mBrowserApp->GetPreferences(curEvent->RequestId(), prefNamePtrs, count); + } else { + mBrowserApp->ObservePreferences(curEvent->RequestId(), prefNamePtrs, count); + } + break; + } + + case AndroidGeckoEvent::PREFERENCES_REMOVE_OBSERVERS: + mBrowserApp->RemovePreferenceObservers(curEvent->RequestId()); + break; + case AndroidGeckoEvent::LOW_MEMORY: // TODO hook in memory-reduction stuff for different levels here if (curEvent->MetaState() >= AndroidGeckoEvent::MEMORY_PRESSURE_MEDIUM) { diff --git a/widget/android/nsIAndroidBridge.idl b/widget/android/nsIAndroidBridge.idl index b7e05f0fa8b..e214391373c 100644 --- a/widget/android/nsIAndroidBridge.idl +++ b/widget/android/nsIAndroidBridge.idl @@ -11,9 +11,16 @@ interface nsIBrowserTab : nsISupports { readonly attribute float scale; }; -[scriptable, uuid(d10377b4-1c90-493a-a532-63cb3f16ee2b)] +[scriptable, uuid(7508b826-4129-40a0-91da-2a6bba33681f)] interface nsIAndroidBrowserApp : nsISupports { nsIBrowserTab getBrowserTab(in int32_t tabId); + void getPreferences(in int32_t requestId, + [array, size_is(count)] in wstring prefNames, + in unsigned long count); + void observePreferences(in int32_t requestId, + [array, size_is(count)] in wstring prefNames, + in unsigned long count); + void removePreferenceObservers(in int32_t requestId); }; [scriptable, uuid(59cfcb35-69b7-47b2-8155-32b193272666)] interface nsIAndroidViewport : nsISupports {