Bug 1337467 - Convert observers to bundle events; r=rbarker r=sebastian

Bug 1337467 - 1. Convert "Window:Resize" observer to event; r=rbarker

Bug 1337467 - 2. Convert "ScrollTo:FocusedInput" observer to event; r=rbarker

Bug 1337467 - 3. Convert "Update:CheckResult" observer to event; r=sebastian

Also remove notifyCheckUpdateResult from GeckoInterface.

Bug 1337467 - 4. Convert "GeckoView:ImportScript" observer to event; r=sebastian

Bug 1337467 - 5. Convert accessibility observers to events; r=sebastian

Bug 1337467 - 6. Convert media/casting observers to events; r=sebastian

Bug 1337467 - 7. Convert "Sanitize:ClearData" observer to event; r=sebastian

Bug 1337467 - 8. Convert "Notification:Event" observer to event; r=sebastian

Bug 1337467 - 9. Convert BrowserApp observers to events; r=sebastian

Bug 1337467 - 10. Convert Tab observers to events; r=sebastian

Bug 1337467 - 11. Convert "Passwords:Init" and "FormHistory:Init" observers to events; r=sebastian

Bug 1337467 - 12. Convert Reader observers to events; r=sebastian

Bug 1337467 - 13. Convert Distribution observers to events; r=sebastian

Bug 1337467 - 14. Convert "Fonts:Reload" observer to event; r=sebastian

Bug 1337467 - 15. Convert RecentTabsAdapter observers to events; r=sebastian

Bug 1337467 - 16. Convert "Session:Prefetch" observer to event; r=sebastian

Bug 1337467 - 17. Convert "Browser:Quit" and "FullScreen:Exit" observers to events; r=sebastian

Bug 1337467 - 18. Convert SessionStore observers to events; r=sebastian

The "Session:NotifyLocationChange" observer is sent by browser.js and
requires passing a browser reference, so it's left as an observer.

Bug 1337467 - 19. Remove unused "Tab:Screenshot:Cancel" notifyObserver call; r=me

Bug 1337467 - 20. Convert "Session:Navigate" observer to event; r=sebastian

Bug 1337467 - 21. Convert "Locale:*" observers to events; r=sebastian

Bug 1337467 - Add log for unhandled events; r=me

Add back the log indicating no listener for an event, which can be
useful when reading logcat. r=me for trivial change.

Bug 1337467 - Don't return error from EventDispatcher when OnEvent fails; r=me

When a listener's OnEvent method returns an error, continue to dispatch
to other listeners and don't return an error from the dispatch function.
This avoids unexpected errors when dispatching events. r=me for trivial
patch.
This commit is contained in:
Jim Chen 2017-03-07 12:34:04 -05:00
Родитель 1050582167
Коммит 1294cccf48
46 изменённых файлов: 724 добавлений и 770 удалений

Просмотреть файл

@ -15,6 +15,10 @@ this.EXPORTED_SYMBOLS = ['AccessFu']; // jshint ignore:line
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
if (Utils.MozBuildApp === 'mobile/android') {
Cu.import('resource://gre/modules/Messaging.jsm');
}
const ACCESSFU_DISABLE = 0; // jshint ignore:line
const ACCESSFU_ENABLE = 1;
const ACCESSFU_AUTO = 2;
@ -32,11 +36,9 @@ this.AccessFu = { // jshint ignore:line
attach: function attach(aWindow) {
Utils.init(aWindow);
try {
Services.androidBridge.dispatch('Accessibility:Ready');
Services.obs.addObserver(this, 'Accessibility:Settings', false);
} catch (x) {
// Not on Android
if (Utils.MozBuildApp === 'mobile/android') {
EventDispatcher.instance.dispatch('Accessibility:Ready');
EventDispatcher.instance.registerListener(this, 'Accessibility:Settings');
}
this._activatePref = new PrefCache(
@ -54,7 +56,7 @@ this.AccessFu = { // jshint ignore:line
this._disable();
}
if (Utils.MozBuildApp === 'mobile/android') {
Services.obs.removeObserver(this, 'Accessibility:Settings');
EventDispatcher.instance.unregisterListener(this, 'Accessibility:Settings');
}
delete this._activatePref;
Utils.uninit();
@ -120,16 +122,21 @@ this.AccessFu = { // jshint ignore:line
Output.start();
PointerAdapter.start();
if (Utils.MozBuildApp === 'mobile/android') {
EventDispatcher.instance.registerListener(this, [
'Accessibility:ActivateObject',
'Accessibility:Focus',
'Accessibility:LongPress',
'Accessibility:MoveByGranularity',
'Accessibility:NextObject',
'Accessibility:PreviousObject',
'Accessibility:ScrollBackward',
'Accessibility:ScrollForward',
]);
}
Services.obs.addObserver(this, 'remote-browser-shown', false);
Services.obs.addObserver(this, 'inprocess-browser-shown', false);
Services.obs.addObserver(this, 'Accessibility:NextObject', false);
Services.obs.addObserver(this, 'Accessibility:PreviousObject', false);
Services.obs.addObserver(this, 'Accessibility:Focus', false);
Services.obs.addObserver(this, 'Accessibility:ActivateObject', false);
Services.obs.addObserver(this, 'Accessibility:LongPress', false);
Services.obs.addObserver(this, 'Accessibility:ScrollForward', false);
Services.obs.addObserver(this, 'Accessibility:ScrollBackward', false);
Services.obs.addObserver(this, 'Accessibility:MoveByGranularity', false);
Utils.win.addEventListener('TabOpen', this);
Utils.win.addEventListener('TabClose', this);
Utils.win.addEventListener('TabSelect', this);
@ -169,14 +176,19 @@ this.AccessFu = { // jshint ignore:line
Services.obs.removeObserver(this, 'remote-browser-shown');
Services.obs.removeObserver(this, 'inprocess-browser-shown');
Services.obs.removeObserver(this, 'Accessibility:NextObject');
Services.obs.removeObserver(this, 'Accessibility:PreviousObject');
Services.obs.removeObserver(this, 'Accessibility:Focus');
Services.obs.removeObserver(this, 'Accessibility:ActivateObject');
Services.obs.removeObserver(this, 'Accessibility:LongPress');
Services.obs.removeObserver(this, 'Accessibility:ScrollForward');
Services.obs.removeObserver(this, 'Accessibility:ScrollBackward');
Services.obs.removeObserver(this, 'Accessibility:MoveByGranularity');
if (Utils.MozBuildApp === 'mobile/android') {
EventDispatcher.instance.unregisterListener(this, [
'Accessibility:ActivateObject',
'Accessibility:Focus',
'Accessibility:LongPress',
'Accessibility:MoveByGranularity',
'Accessibility:NextObject',
'Accessibility:PreviousObject',
'Accessibility:ScrollBackward',
'Accessibility:ScrollForward',
]);
}
delete this._quicknavModesPref;
delete this._notifyOutputPref;
@ -288,24 +300,23 @@ this.AccessFu = { // jshint ignore:line
this._loadFrameScript(aMessageManager);
},
observe: function observe(aSubject, aTopic, aData) {
switch (aTopic) {
onEvent: function (event, data, callback) {
switch (event) {
case 'Accessibility:Settings':
this._systemPref = JSON.parse(aData).enabled;
this._systemPref = data.enabled;
this._enableOrDisable();
break;
case 'Accessibility:NextObject':
case 'Accessibility:PreviousObject':
{
let rule = aData ?
aData.substr(0, 1).toUpperCase() + aData.substr(1).toLowerCase() :
case 'Accessibility:PreviousObject': {
let rule = data ?
data.rule.substr(0, 1).toUpperCase() + data.rule.substr(1).toLowerCase() :
'Simple';
let method = aTopic.replace(/Accessibility:(\w+)Object/, 'move$1');
let method = event.replace(/Accessibility:(\w+)Object/, 'move$1');
this.Input.moveCursor(method, rule, 'gesture');
break;
}
case 'Accessibility:ActivateObject':
this.Input.activateCurrent(JSON.parse(aData));
this.Input.activateCurrent(data);
break;
case 'Accessibility:LongPress':
this.Input.sendContextMenuMessage();
@ -317,14 +328,19 @@ this.AccessFu = { // jshint ignore:line
this.Input.androidScroll('backward');
break;
case 'Accessibility:Focus':
this._focused = JSON.parse(aData);
this._focused = data.gainFocus;
if (this._focused) {
this.autoMove({ forcePresent: true, noOpIfOnScreen: true });
}
break;
case 'Accessibility:MoveByGranularity':
this.Input.moveByGranularity(JSON.parse(aData));
this.Input.moveByGranularity(data);
break;
}
},
observe: function observe(aSubject, aTopic, aData) {
switch (aTopic) {
case 'remote-browser-shown':
case 'inprocess-browser-shown':
{

Просмотреть файл

@ -358,12 +358,11 @@ ChromecastRemoteDisplayDevice.prototype = {
};
function AndroidCastDeviceProvider() {
this._listener = null;
this._deviceList = new Map();
}
AndroidCastDeviceProvider.prototype = {
_listener: null,
_deviceList: new Map(),
onSessionRequest: function APDP_onSessionRequest(aDeviceId,
aUrl,
aPresentationId,
@ -403,18 +402,23 @@ AndroidCastDeviceProvider.prototype = {
// When unload this provider.
if (!this._listener) {
// remove observer
Services.obs.removeObserver(this, TOPIC_ANDROID_CAST_DEVICE_ADDED);
Services.obs.removeObserver(this, TOPIC_ANDROID_CAST_DEVICE_CHANGED);
Services.obs.removeObserver(this, TOPIC_ANDROID_CAST_DEVICE_REMOVED);
EventDispatcher.instance.unregisterListener(this, [
TOPIC_ANDROID_CAST_DEVICE_ADDED,
TOPIC_ANDROID_CAST_DEVICE_CHANGED,
TOPIC_ANDROID_CAST_DEVICE_REMOVED,
]);
return;
}
// Observer registration
EventDispatcher.instance.registerListener(this, [
TOPIC_ANDROID_CAST_DEVICE_ADDED,
TOPIC_ANDROID_CAST_DEVICE_CHANGED,
TOPIC_ANDROID_CAST_DEVICE_REMOVED,
]);
// Sync all device already found by Android.
EventDispatcher.instance.sendRequest({ type: TOPIC_ANDROID_CAST_DEVICE_SYNCDEVICE });
// Observer registration
Services.obs.addObserver(this, TOPIC_ANDROID_CAST_DEVICE_ADDED, false);
Services.obs.addObserver(this, TOPIC_ANDROID_CAST_DEVICE_CHANGED, false);
Services.obs.addObserver(this, TOPIC_ANDROID_CAST_DEVICE_REMOVED, false);
},
get listener() {
@ -425,13 +429,11 @@ AndroidCastDeviceProvider.prototype = {
// There is no API to do force discovery in Android SDK.
},
// nsIObserver
observe: function APDP_observe(aSubject, aTopic, aData) {
log('observe ' + aTopic + ': ' + aData);
switch (aTopic) {
onEvent: function APDP_onEvent(event, data, callback) {
switch (event) {
case TOPIC_ANDROID_CAST_DEVICE_ADDED:
case TOPIC_ANDROID_CAST_DEVICE_CHANGED: {
let deviceInfo = JSON.parse(aData);
let deviceInfo = data;
let deviceId = deviceInfo.uuid;
if (!this._deviceList.has(deviceId)) {
@ -449,7 +451,7 @@ AndroidCastDeviceProvider.prototype = {
break;
}
case TOPIC_ANDROID_CAST_DEVICE_REMOVED: {
let deviceId = aData;
let deviceId = data.id;
if (!this._deviceList.has(deviceId)) {
break;
}

Просмотреть файл

@ -16,7 +16,6 @@ import android.support.annotation.UiThread;
import android.graphics.Rect;
import org.json.JSONArray;
import org.mozilla.gecko.activitystream.ActivityStream;
import org.mozilla.gecko.adjust.AdjustBrowserAppDelegate;
import org.mozilla.gecko.annotation.RobocopTarget;
@ -168,8 +167,6 @@ import org.mozilla.gecko.switchboard.AsyncConfigLoader;
import org.mozilla.gecko.switchboard.SwitchBoard;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileNotFoundException;
@ -1381,13 +1378,9 @@ public class BrowserApp extends GeckoApp
// This can be selected from either the browser menu or the contextmenu, depending on the size and version (v11+) of the phone.
Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null && tab.hasFeeds()) {
JSONObject args = new JSONObject();
try {
args.put("tabId", tab.getId());
} catch (JSONException e) {
Log.e(LOGTAG, "error building json arguments", e);
}
GeckoAppShell.notifyObservers("Feeds:Subscribe", args.toString());
final GeckoBundle args = new GeckoBundle(1);
args.putInt("tabId", tab.getId());
EventDispatcher.getInstance().dispatch("Feeds:Subscribe", args);
}
return true;
}
@ -1917,7 +1910,9 @@ public class BrowserApp extends GeckoApp
new AlertDialog.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
GeckoAppShell.notifyObservers("CharEncoding:Set", codeArray[which]);
final GeckoBundle data = new GeckoBundle(1);
data.putString("encoding", codeArray[which]);
EventDispatcher.getInstance().dispatch("CharEncoding:Set", data);
dialog.dismiss();
}
});
@ -1941,8 +1936,7 @@ public class BrowserApp extends GeckoApp
case "Experiments:GetActive":
final List<String> experiments = SwitchBoard.getActiveExperiments(this);
final JSONArray json = new JSONArray(experiments);
callback.sendSuccess(json.toString());
callback.sendSuccess(experiments.toArray(new String[experiments.size()]));
break;
case "Experiments:SetOverride":
@ -3162,7 +3156,9 @@ public class BrowserApp extends GeckoApp
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
GeckoAppShell.notifyObservers("Menu:Clicked", Integer.toString(info.id - ADDON_MENU_OFFSET));
final GeckoBundle data = new GeckoBundle(1);
data.putInt("item", info.id - ADDON_MENU_OFFSET);
EventDispatcher.getInstance().dispatch("Menu:Clicked", data);
return true;
}
});
@ -3674,7 +3670,7 @@ public class BrowserApp extends GeckoApp
if (itemId == R.id.save_as_pdf) {
Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, TelemetryContract.Method.MENU, "pdf");
GeckoAppShell.notifyObservers("SaveAs:PDF", null);
EventDispatcher.getInstance().dispatch("SaveAs:PDF", null);
return true;
}
@ -3719,7 +3715,7 @@ public class BrowserApp extends GeckoApp
}
if (itemId == R.id.char_encoding) {
GeckoAppShell.notifyObservers("CharEncoding:Get", null);
EventDispatcher.getInstance().dispatch("CharEncoding:Get", null);
return true;
}
@ -3732,14 +3728,10 @@ public class BrowserApp extends GeckoApp
Tab selectedTab = Tabs.getInstance().getSelectedTab();
if (selectedTab == null)
return true;
JSONObject args = new JSONObject();
try {
args.put("desktopMode", !item.isChecked());
args.put("tabId", selectedTab.getId());
} catch (JSONException e) {
Log.e(LOGTAG, "error building json arguments", e);
}
GeckoAppShell.notifyObservers("DesktopMode:Change", args.toString());
final GeckoBundle args = new GeckoBundle(2);
args.putBoolean("desktopMode", !item.isChecked());
args.putInt("tabId", selectedTab.getId());
EventDispatcher.getInstance().dispatch("DesktopMode:Change", args);
return true;
}
@ -3952,7 +3944,7 @@ public class BrowserApp extends GeckoApp
// If we've reached our magic number, show the feedback page.
if (launchCount == FEEDBACK_LAUNCH_COUNT) {
GeckoAppShell.notifyObservers("Feedback:Show", null);
EventDispatcher.getInstance().dispatch("Feedback:Show", null);
}
}
} finally {
@ -3961,19 +3953,9 @@ public class BrowserApp extends GeckoApp
}
public void openUrls(List<String> urls) {
try {
JSONArray array = new JSONArray();
for (String url : urls) {
array.put(url);
}
JSONObject object = new JSONObject();
object.put("urls", array);
GeckoAppShell.notifyObservers("Tabs:OpenMultiple", object.toString());
} catch (JSONException e) {
Log.e(LOGTAG, "Unable to create JSON for opening multiple URLs");
}
final GeckoBundle data = new GeckoBundle(1);
data.putStringArray("urls", urls.toArray(new String[urls.size()]));
EventDispatcher.getInstance().dispatch("Tabs:OpenMultiple", data);
}
private void showTabQueuePromptIfApplicable(final SafeIntent intent) {

Просмотреть файл

@ -17,6 +17,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.annotation.ReflectionTarget;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.GeckoJarReader;
import android.content.BroadcastReceiver;
@ -220,8 +221,9 @@ public class BrowserLocaleManager implements LocaleManager {
// The value we send to Gecko should be a language tag, not
// a Java locale string.
final String osLanguageTag = Locales.getLanguageTag(osLocale);
GeckoAppShell.notifyObservers("Locale:OS", osLanguageTag);
final GeckoBundle data = new GeckoBundle(1);
data.putString("languageTag", Locales.getLanguageTag(osLocale));
EventDispatcher.getInstance().dispatch("Locale:OS", data);
}
@Override
@ -265,7 +267,9 @@ public class BrowserLocaleManager implements LocaleManager {
persistLocale(context, localeCode);
// Tell Gecko.
GeckoAppShell.notifyObservers(EVENT_LOCALE_CHANGED, Locales.getLanguageTag(getCurrentLocale(context)));
final GeckoBundle data = new GeckoBundle(1);
data.putString("languageTag", Locales.getLanguageTag(getCurrentLocale(context)));
EventDispatcher.getInstance().dispatch(EVENT_LOCALE_CHANGED, data);
return resultant;
}
@ -280,7 +284,7 @@ public class BrowserLocaleManager implements LocaleManager {
updateLocale(context, systemLocale);
// Tell Gecko.
GeckoAppShell.notifyObservers(EVENT_LOCALE_CHANGED, "");
EventDispatcher.getInstance().dispatch(EVENT_LOCALE_CHANGED, null);
}
/**

Просмотреть файл

@ -6,11 +6,9 @@
package org.mozilla.gecko;
import org.json.JSONObject;
import org.json.JSONException;
import org.mozilla.gecko.R;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import com.google.android.gms.cast.CastDevice;
import com.google.android.gms.cast.CastRemoteDisplayLocalService;
@ -44,19 +42,16 @@ public class ChromeCastDisplay implements GeckoPresentationDisplay {
this.castDevice = CastDevice.getFromBundle(route.getExtras());
}
public JSONObject toJSON() {
final JSONObject obj = new JSONObject();
try {
if (castDevice == null) {
return null;
}
obj.put("uuid", route.getId());
obj.put("friendlyName", castDevice.getFriendlyName());
obj.put("type", "chromecast");
} catch (JSONException ex) {
Log.d(LOGTAG, "Error building route", ex);
@Override // GeckoPresentationDisplay
public GeckoBundle toBundle() {
if (castDevice == null) {
return null;
}
final GeckoBundle obj = new GeckoBundle(3);
obj.putString("uuid", route.getId());
obj.putString("friendlyName", castDevice.getFriendlyName());
obj.putString("type", "chromecast");
return obj;
}

Просмотреть файл

@ -9,8 +9,6 @@ import java.io.IOException;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import org.json.JSONObject;
import org.json.JSONException;
import com.google.android.gms.cast.Cast.MessageReceivedCallback;
import com.google.android.gms.cast.ApplicationMetadata;
@ -185,27 +183,22 @@ class ChromeCastPlayer implements GeckoMediaPlayer {
* easier to filter out duplicate devices from different sources in JS.
* Returns null if the device can't be found.
*/
@Override
public JSONObject toJSON() {
final JSONObject obj = new JSONObject();
try {
final CastDevice device = CastDevice.getFromBundle(route.getExtras());
if (device == null) {
return null;
}
obj.put("uuid", route.getId());
obj.put("version", device.getDeviceVersion());
obj.put("friendlyName", device.getFriendlyName());
obj.put("location", device.getIpAddress().toString());
obj.put("modelName", device.getModelName());
obj.put("mirror", canMirror);
// For now we just assume all of these are Google devices
obj.put("manufacturer", "Google Inc.");
} catch (JSONException ex) {
debug("Error building route", ex);
@Override // GeckoMediaPlayer
public GeckoBundle toBundle() {
final CastDevice device = CastDevice.getFromBundle(route.getExtras());
if (device == null) {
return null;
}
final GeckoBundle obj = new GeckoBundle(7);
obj.putString("uuid", route.getId());
obj.putString("version", device.getDeviceVersion());
obj.putString("friendlyName", device.getFriendlyName());
obj.putString("location", device.getIpAddress().toString());
obj.putString("modelName", device.getModelName());
obj.putBoolean("mirror", canMirror);
// For now we just assume all of these are Google devices
obj.putString("manufacturer", "Google Inc.");
return obj;
}

Просмотреть файл

@ -545,7 +545,7 @@ public abstract class GeckoApp
public boolean onMenuOpened(int featureId, Menu menu) {
// exit full-screen mode whenever the menu is opened
if (mLayerView != null && mLayerView.isFullScreen()) {
GeckoAppShell.notifyObservers("FullScreen:Exit", null);
EventDispatcher.getInstance().dispatch("FullScreen:Exit", null);
}
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
@ -572,43 +572,34 @@ public abstract class GeckoApp
GuestSession.hideNotification(this);
final SharedPreferences prefs = getSharedPreferencesForProfile();
final Set<String> clearSet =
PrefUtils.getStringSet(prefs, ClearOnShutdownPref.PREF, new HashSet<String>());
final Set<String> clearSet = PrefUtils.getStringSet(
prefs, ClearOnShutdownPref.PREF, new HashSet<String>());
final JSONObject clearObj = new JSONObject();
for (String clear : clearSet) {
try {
clearObj.put(clear, true);
} catch (JSONException ex) {
Log.e(LOGTAG, "Error adding clear object " + clear, ex);
}
final GeckoBundle clearObj = new GeckoBundle(clearSet.size());
for (final String clear : clearSet) {
clearObj.putBoolean(clear, true);
}
final JSONObject res = new JSONObject();
try {
res.put("sanitize", clearObj);
} catch (JSONException ex) {
Log.e(LOGTAG, "Error adding sanitize object", ex);
final GeckoBundle res = new GeckoBundle(2);
res.putBundle("sanitize", clearObj);
// If the user wants to clear open tabs, or else has opted out of session
// restore and does want to clear history, we also want to prevent the current
// session info from being saved.
if (clearObj.containsKey("private.data.openTabs")) {
res.putBoolean("dontSaveSession", true);
} else if (clearObj.containsKey("private.data.history")) {
final String sessionRestore =
getSessionRestorePreference(getSharedPreferences());
res.putBoolean("dontSaveSession", "quit".equals(sessionRestore));
}
// If the user wants to clear open tabs, or else has opted out of session restore and does want to clear history,
// we also want to prevent the current session info from being saved.
try {
if (clearObj.has("private.data.openTabs")) {
res.put("dontSaveSession", true);
} else if (clearObj.has("private.data.history")) {
EventDispatcher.getInstance().dispatch("Browser:Quit", res);
final String sessionRestore = getSessionRestorePreference(getSharedPreferences());
res.put("dontSaveSession", "quit".equals(sessionRestore));
}
} catch (JSONException ex) {
Log.e(LOGTAG, "Error adding session restore data", ex);
}
GeckoAppShell.notifyObservers("Browser:Quit", res.toString());
// We don't call doShutdown() here because this creates a race condition which can
// cause the clearing of private data to fail. Instead, we shut down the UI only after
// we're done sanitizing.
// We don't call doShutdown() here because this creates a race condition which
// can cause the clearing of private data to fail. Instead, we shut down the
// UI only after we're done sanitizing.
return true;
}
@ -1347,7 +1338,7 @@ public abstract class GeckoApp
@Override
public void run() {
// If we are doing a restore, read the session data so we can send it to Gecko later.
String restoreMessage = null;
GeckoBundle restoreMessage = null;
if (!mIsRestoringActivity && mShouldRestore) {
final boolean isExternalURL = invokedWithExternalURL(getIntentURI(new SafeIntent(getIntent())));
try {
@ -1406,7 +1397,7 @@ public abstract class GeckoApp
// If we are doing a restore, send the parsed session data to Gecko.
if (!mIsRestoringActivity) {
GeckoAppShell.notifyObservers("Session:Restore", restoreMessage);
EventDispatcher.getInstance().dispatch("Session:Restore", restoreMessage);
}
// Make sure sessionstore.old is either updated or deleted as necessary.
@ -1791,56 +1782,58 @@ public abstract class GeckoApp
}
@WorkerThread
private String restoreSessionTabs(final boolean isExternalURL, boolean useBackup) throws SessionRestoreException {
try {
String sessionString = getProfile().readSessionFile(useBackup);
if (sessionString == null) {
throw new SessionRestoreException("Could not read from session file");
}
private GeckoBundle restoreSessionTabs(final boolean isExternalURL, boolean useBackup)
throws SessionRestoreException {
String sessionString = getProfile().readSessionFile(useBackup);
if (sessionString == null) {
throw new SessionRestoreException("Could not read from session file");
}
// If we are doing an OOM restore, parse the session data and
// stub the restored tabs immediately. This allows the UI to be
// updated before Gecko has restored.
final JSONArray tabs = new JSONArray();
final JSONObject windowObject = new JSONObject();
final boolean sessionDataValid;
// If we are doing an OOM restore, parse the session data and
// stub the restored tabs immediately. This allows the UI to be
// updated before Gecko has restored.
final JSONArray tabs = new JSONArray();
final JSONObject windowObject = new JSONObject();
final boolean sessionDataValid;
LastSessionParser parser = new LastSessionParser(tabs, windowObject, isExternalURL);
LastSessionParser parser = new LastSessionParser(tabs, windowObject, isExternalURL);
if (mPrivateBrowsingSession == null) {
sessionDataValid = parser.parse(sessionString);
} else {
sessionDataValid = parser.parse(sessionString, mPrivateBrowsingSession);
}
if (mPrivateBrowsingSession == null) {
sessionDataValid = parser.parse(sessionString);
} else {
sessionDataValid = parser.parse(sessionString, mPrivateBrowsingSession);
}
if (tabs.length() > 0) {
if (tabs.length() > 0) {
try {
// Update all parent tab IDs ...
parser.updateParentId(tabs);
windowObject.put("tabs", tabs);
// ... and for recently closed tabs as well (if we've got any).
JSONArray closedTabs = windowObject.optJSONArray("closedTabs");
final JSONArray closedTabs = windowObject.optJSONArray("closedTabs");
parser.updateParentId(closedTabs);
windowObject.putOpt("closedTabs", closedTabs);
sessionString = new JSONObject().put("windows", new JSONArray().put(windowObject)).toString();
} else {
if (parser.allTabsSkipped() || sessionDataValid) {
// If we intentionally skipped all tabs we've read from the session file, we
// set mShouldRestore back to false at this point already, so the calling code
// can infer that the exception wasn't due to a damaged session store file.
// The same applies if the session file was syntactically valid and
// simply didn't contain any tabs.
mShouldRestore = false;
}
throw new SessionRestoreException("No tabs could be read from session file");
sessionString = new JSONObject().put(
"windows", new JSONArray().put(windowObject)).toString();
} catch (final JSONException e) {
throw new SessionRestoreException(e);
}
JSONObject restoreData = new JSONObject();
restoreData.put("sessionString", sessionString);
return restoreData.toString();
} catch (JSONException e) {
throw new SessionRestoreException(e);
} else {
if (parser.allTabsSkipped() || sessionDataValid) {
// If we intentionally skipped all tabs we've read from the session file, we
// set mShouldRestore back to false at this point already, so the calling code
// can infer that the exception wasn't due to a damaged session store file.
// The same applies if the session file was syntactically valid and
// simply didn't contain any tabs.
mShouldRestore = false;
}
throw new SessionRestoreException("No tabs could be read from session file");
}
final GeckoBundle restoreData = new GeckoBundle(1);
restoreData.putString("sessionString", sessionString);
return restoreData;
}
@RobocopTarget
@ -2616,7 +2609,7 @@ public abstract class GeckoApp
}
if (mLayerView != null && mLayerView.isFullScreen()) {
GeckoAppShell.notifyObservers("FullScreen:Exit", null);
EventDispatcher.getInstance().dispatch("FullScreen:Exit", null);
return;
}
@ -2654,8 +2647,9 @@ public abstract class GeckoApp
onDone();
Tab nextSelectedTab = Tabs.getInstance().getNextTab(tab);
if (nextSelectedTab != null) {
int nextSelectedTabId = nextSelectedTab.getId();
GeckoAppShell.notifyObservers("Tab:KeepZombified", Integer.toString(nextSelectedTabId));
final GeckoBundle data = new GeckoBundle(1);
data.putInt("nextSelectedTabId", nextSelectedTab.getId());
EventDispatcher.getInstance().dispatch("Tab:KeepZombified", data);
}
tabs.closeTab(tab);
return;
@ -2720,11 +2714,6 @@ public abstract class GeckoApp
}
}
@Override
public void notifyCheckUpdateResult(String result) {
GeckoAppShell.notifyObservers("Update:CheckResult", result);
}
private void geckoConnected() {
mLayerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
}

Просмотреть файл

@ -5,8 +5,8 @@
package org.mozilla.gecko;
import org.json.JSONObject;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
/**
* Wrapper for MediaRouter types supported by Android, such as Chromecast, Miracast, etc.
@ -15,7 +15,7 @@ interface GeckoMediaPlayer {
/**
* Can return null.
*/
JSONObject toJSON();
GeckoBundle toBundle();
void load(String title, String url, String type, EventCallback callback);
void play(EventCallback callback);
void pause(EventCallback callback);

Просмотреть файл

@ -13,7 +13,7 @@ public class GeckoMessageReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (GeckoApp.ACTION_INIT_PW.equals(action)) {
GeckoAppShell.notifyObservers("Passwords:Init", null);
EventDispatcher.getInstance().dispatch("Passwords:Init", null);
}
}
}

Просмотреть файл

@ -5,8 +5,8 @@
package org.mozilla.gecko;
import org.json.JSONObject;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
/**
* Wrapper for MediaRouter types supported by Android to use for
@ -16,7 +16,7 @@ interface GeckoPresentationDisplay {
/**
* Can return null.
*/
JSONObject toJSON();
GeckoBundle toBundle();
void start(EventCallback callback);
void stop(EventCallback callback);
}

Просмотреть файл

@ -6,6 +6,7 @@
package org.mozilla.gecko;
import org.mozilla.gecko.updater.UpdateServiceHelper;
import org.mozilla.gecko.util.GeckoBundle;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -16,10 +17,9 @@ public class GeckoUpdateReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent) {
if (UpdateServiceHelper.ACTION_CHECK_UPDATE_RESULT.equals(intent.getAction())) {
String result = intent.getStringExtra("result");
if (GeckoAppShell.getGeckoInterface() != null && result != null) {
GeckoAppShell.getGeckoInterface().notifyCheckUpdateResult(result);
}
final GeckoBundle data = new GeckoBundle(1);
data.putString("result", intent.getStringExtra("result"));
GeckoApp.getEventDispatcher().dispatch("Update:CheckResult", data);
}
}
}

Просмотреть файл

@ -162,11 +162,11 @@ public class MediaPlayerManager extends Fragment implements BundleEventListener
} else if ("AndroidCastDevice:SyncDevice".equals(event)) {
for (Map.Entry<String, GeckoPresentationDisplay> entry : displays.entrySet()) {
GeckoPresentationDisplay display = entry.getValue();
JSONObject json = display.toJSON();
if (json == null) {
final GeckoBundle data = display.toBundle();
if (data == null) {
break;
}
GeckoAppShell.notifyObservers("AndroidCastDevice:Added", json.toString());
EventDispatcher.getInstance().dispatch("AndroidCastDevice:Added", data);
}
}
}
@ -180,12 +180,15 @@ public class MediaPlayerManager extends Fragment implements BundleEventListener
// Remove from media player list.
players.remove(route.getId());
GeckoAppShell.notifyObservers("MediaPlayer:Removed", route.getId());
final GeckoBundle data = new GeckoBundle(1);
data.putString("id", route.getId());
EventDispatcher.getInstance().dispatch("MediaPlayer:Removed", data);
updatePresentation();
// Remove from presentation display list.
if (displays.remove(route.getId()) != null) {
GeckoAppShell.notifyObservers("AndroidCastDevice:Removed", route.getId());
EventDispatcher.getInstance().dispatch("AndroidCastDevice:Removed", data);
}
}
@ -238,13 +241,13 @@ public class MediaPlayerManager extends Fragment implements BundleEventListener
return;
}
final JSONObject json = player.toJSON();
if (json == null) {
final GeckoBundle data = player.toBundle();
if (data == null) {
return;
}
players.put(route.getId(), player);
GeckoAppShell.notifyObservers(eventName, json.toString());
EventDispatcher.getInstance().dispatch(eventName, data);
}
private void saveAndNotifyOfDisplay(final String eventName,
@ -254,13 +257,13 @@ public class MediaPlayerManager extends Fragment implements BundleEventListener
return;
}
final JSONObject json = display.toJSON();
if (json == null) {
final GeckoBundle data = display.toBundle();
if (data == null) {
return;
}
displays.put(route.getId(), display);
GeckoAppShell.notifyObservers(eventName, json.toString());
EventDispatcher.getInstance().dispatch(eventName, data);
}
};

Просмотреть файл

@ -575,12 +575,12 @@ public class Tab {
if (!canDoBack())
return false;
GeckoAppShell.notifyObservers("Session:Back", "");
EventDispatcher.getInstance().dispatch("Session:Back", null);
return true;
}
public void doStop() {
GeckoAppShell.notifyObservers("Session:Stop", "");
EventDispatcher.getInstance().dispatch("Session:Stop", null);
}
// Our version of nsSHistory::GetCanGoForward
@ -592,7 +592,7 @@ public class Tab {
if (!canDoForward())
return false;
GeckoAppShell.notifyObservers("Session:Forward", "");
EventDispatcher.getInstance().dispatch("Session:Forward", null);
return true;
}

Просмотреть файл

@ -7,7 +7,7 @@ package org.mozilla.gecko.db;
import java.lang.IllegalArgumentException;
import java.util.HashMap;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.db.BrowserContract.FormHistory;
import org.mozilla.gecko.db.BrowserContract.DeletedFormHistory;
import org.mozilla.gecko.db.BrowserContract;
@ -124,7 +124,7 @@ public class FormHistoryProvider extends SQLiteBridgeContentProvider {
@Override
public void initGecko() {
GeckoAppShell.notifyObservers("FormHistory:Init", null);
EventDispatcher.getInstance().dispatch("FormHistory:Init", null);
}
@Override

Просмотреть файл

@ -38,11 +38,13 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.annotation.JNITarget;
import org.mozilla.gecko.util.FileUtils;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.ThreadUtils;
@ -223,7 +225,7 @@ public class Distribution {
public void run() {
boolean distributionSet = distribution.doInit();
if (distributionSet) {
String preferencesJSON = "";
GeckoBundle data = null;
try {
final File descFile = distribution.getDistributionFile("preferences.json");
if (descFile == null) {
@ -231,11 +233,15 @@ public class Distribution {
// preferences.json file.
throw new IOException("preferences.json not found");
}
preferencesJSON = FileUtils.readStringFromFile(descFile);
final String preferencesJSON = FileUtils.readStringFromFile(descFile);
data = new GeckoBundle(1);
data.putString("preferences", preferencesJSON);
} catch (IOException e) {
Log.e(LOGTAG, "Error getting distribution descriptor file.", e);
}
GeckoAppShell.notifyObservers("Distribution:Set", preferencesJSON);
EventDispatcher.getInstance().dispatch("Distribution:Set", data);
}
}
});
@ -343,7 +349,7 @@ public class Distribution {
runLateReadyQueue();
// Make sure that changes to search defaults are applied immediately.
GeckoAppShell.notifyObservers("Distribution:Changed", "");
EventDispatcher.getInstance().dispatch("Distribution:Changed", null);
}
/**

Просмотреть файл

@ -8,10 +8,8 @@ package org.mozilla.gecko.distribution;
import org.mozilla.gecko.AdjustConstants;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoAppShell;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoBundle;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -92,16 +90,10 @@ public class ReferrerReceiver extends BroadcastReceiver {
return;
}
try {
final JSONObject data = new JSONObject();
data.put("id", "playstore");
data.put("version", referrer.campaign);
String payload = data.toString();
// Try to make sure the prefs are written as a group.
GeckoAppShell.notifyObservers("Campaign:Set", payload);
} catch (JSONException e) {
Log.e(LOGTAG, "Error propagating campaign identifier.", e);
}
final GeckoBundle data = new GeckoBundle(2);
data.putString("id", "playstore");
data.putString("version", referrer.campaign);
// Try to make sure the prefs are written as a group.
EventDispatcher.getInstance().dispatch("Campaign:Set", data);
}
}

Просмотреть файл

@ -6,7 +6,7 @@
package org.mozilla.gecko.dlc;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.dlc.catalog.DownloadContent;
import org.mozilla.gecko.dlc.catalog.DownloadContentCatalog;
import org.mozilla.gecko.util.HardwareUtils;
@ -119,7 +119,7 @@ public class DownloadContentService extends IntentService {
@Override
public void onContentDownloaded(DownloadContent content) {
if (content.isFont()) {
GeckoAppShell.notifyObservers("Fonts:Reload", "");
EventDispatcher.getInstance().dispatch("Fonts:Reload", null);
}
}
});

Просмотреть файл

@ -18,7 +18,6 @@ import java.util.Locale;
import android.content.SharedPreferences;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.PrefsHelper;
import org.mozilla.gecko.R;
@ -497,7 +496,9 @@ public class BrowserSearch extends HomeFragment
}
// Prefetch auto-completed domain since it's a likely target
GeckoAppShell.notifyObservers("Session:Prefetch", "http://" + autocompletion);
final GeckoBundle data = new GeckoBundle(1);
data.putString("url", "http://" + autocompletion);
EventDispatcher.getInstance().dispatch("Session:Prefetch", data);
mAutocompleteHandler.onAutocomplete(autocompletion);
mAutocompleteHandler = null;
@ -597,7 +598,9 @@ public class BrowserSearch extends HomeFragment
if (searchCount == 0) {
// Prefetch the first item in the list since it's weighted the highest
GeckoAppShell.notifyObservers("Session:Prefetch", url);
final GeckoBundle data = new GeckoBundle(1);
data.putString("url", url);
EventDispatcher.getInstance().dispatch("Session:Prefetch", data);
}
// Does the completion match against the whole URL? This will match

Просмотреть файл

@ -35,11 +35,8 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.R;
import org.mozilla.gecko.RemoteClientsDialogFragment;
@ -54,6 +51,7 @@ import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.RemoteClient;
import org.mozilla.gecko.restrictions.Restrictable;
import org.mozilla.gecko.widget.HistoryDividerItemDecoration;
import org.mozilla.gecko.util.GeckoBundle;
import java.util.ArrayList;
import java.util.Collections;
@ -459,14 +457,10 @@ public class CombinedHistoryPanel extends HomeFragment implements RemoteClientsD
dialog.dismiss();
// Send message to Java to clear history.
final JSONObject json = new JSONObject();
try {
json.put("history", true);
} catch (JSONException e) {
Log.e(LOGTAG, "JSON error", e);
}
final GeckoBundle data = new GeckoBundle(1);
data.putBoolean("history", true);
EventDispatcher.getInstance().dispatch("Sanitize:ClearData", data);
GeckoAppShell.notifyObservers("Sanitize:ClearData", json.toString());
Telemetry.sendUIEvent(TelemetryContract.Event.SANITIZE, TelemetryContract.Method.BUTTON, "history");
}
});

Просмотреть файл

@ -13,13 +13,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.AboutPages;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.R;
import org.mozilla.gecko.SessionParser;
@ -84,11 +80,11 @@ public class RecentTabsAdapter extends RecyclerView.Adapter<CombinedHistoryItem>
public void startListeningForClosedTabs() {
EventDispatcher.getInstance().registerUiThreadListener(this, "ClosedTabs:Data");
GeckoAppShell.notifyObservers("ClosedTabs:StartNotifications", null);
EventDispatcher.getInstance().dispatch("ClosedTabs:StartNotifications", null);
}
public void stopListeningForClosedTabs() {
GeckoAppShell.notifyObservers("ClosedTabs:StopNotifications", null);
EventDispatcher.getInstance().dispatch("ClosedTabs:StopNotifications", null);
EventDispatcher.getInstance().unregisterUiThreadListener(this, "ClosedTabs:Data");
recentlyClosedTabsReceived = false;
}
@ -295,14 +291,9 @@ public class RecentTabsAdapter extends RecyclerView.Adapter<CombinedHistoryItem>
}
private static void restoreSessionWithHistory(List<String> dataList) {
final JSONObject json = new JSONObject();
try {
json.put("tabs", new JSONArray(dataList));
} catch (JSONException e) {
Log.e(LOGTAG, "JSON error", e);
}
GeckoAppShell.notifyObservers("Session:RestoreRecentTabs", json.toString());
final GeckoBundle data = new GeckoBundle(1);
data.putStringArray("tabs", dataList);
EventDispatcher.getInstance().dispatch("Session:RestoreRecentTabs", data);
}
@Override

Просмотреть файл

@ -11,8 +11,6 @@ import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
@ -127,27 +125,22 @@ public final class NotificationHelper implements BundleEventListener {
}
public static void getArgsAndSendNotificationIntent(SafeIntent intent) {
final JSONObject args = new JSONObject();
final GeckoBundle args = new GeckoBundle(5);
final Uri data = intent.getData();
final String notificationType = data.getQueryParameter(EVENT_TYPE_ATTR);
try {
args.put(ID_ATTR, data.getQueryParameter(ID_ATTR));
args.put(EVENT_TYPE_ATTR, notificationType);
args.put(HANDLER_ATTR, data.getQueryParameter(HANDLER_ATTR));
args.put(COOKIE_ATTR, intent.getStringExtra(COOKIE_ATTR));
args.putString(ID_ATTR, data.getQueryParameter(ID_ATTR));
args.putString(EVENT_TYPE_ATTR, notificationType);
args.putString(HANDLER_ATTR, data.getQueryParameter(HANDLER_ATTR));
args.putString(COOKIE_ATTR, intent.getStringExtra(COOKIE_ATTR));
if (BUTTON_EVENT.equals(notificationType)) {
final String actionName = data.getQueryParameter(ACTION_ID_ATTR);
args.put(ACTION_ID_ATTR, actionName);
}
Log.i(LOGTAG, "Send " + args.toString());
GeckoAppShell.notifyObservers("Notification:Event", args.toString());
} catch (JSONException e) {
Log.e(LOGTAG, "Error building JSON notification arguments.", e);
if (BUTTON_EVENT.equals(notificationType)) {
final String actionName = data.getQueryParameter(ACTION_ID_ATTR);
args.putString(ACTION_ID_ATTR, actionName);
}
EventDispatcher.getInstance().dispatch("Notification:Event", args);
}
public void handleNotificationIntent(SafeIntent i) {

Просмотреть файл

@ -5,12 +5,11 @@
package org.mozilla.gecko.preferences;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.util.GeckoBundle;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.icons.storage.DiskStorage;
import java.util.Arrays;
@ -40,7 +39,7 @@ class PrivateDataPreference extends MultiPrefMultiChoicePreference {
Telemetry.sendUIEvent(TelemetryContract.Event.SANITIZE, TelemetryContract.Method.DIALOG, "settings");
final Set<String> values = getValues();
final JSONObject json = new JSONObject();
final GeckoBundle data = new GeckoBundle();
for (String value : values) {
// Privacy pref checkbox values are stored in Android prefs to
@ -49,11 +48,7 @@ class PrivateDataPreference extends MultiPrefMultiChoicePreference {
// removed here so we can send the values to Gecko, which then does
// the sanitization for each key.
final String key = value.substring(PREF_KEY_PREFIX.length());
try {
json.put(key, true);
} catch (JSONException e) {
Log.e(LOGTAG, "JSON error", e);
}
data.putBoolean(key, true);
}
if (values.contains("private.data.offlineApps")) {
@ -62,6 +57,6 @@ class PrivateDataPreference extends MultiPrefMultiChoicePreference {
}
// clear private data in gecko
GeckoAppShell.notifyObservers("Sanitize:ClearData", json.toString());
EventDispatcher.getInstance().dispatch("Sanitize:ClearData", data);
}
}

Просмотреть файл

@ -101,17 +101,13 @@ public final class ReadingListHelper implements BundleEventListener {
}
@Override
public void onPostExecute(String faviconUrl) {
JSONObject args = new JSONObject();
public void onPostExecute(final String faviconUrl) {
final GeckoBundle args = new GeckoBundle(2);
if (faviconUrl != null) {
try {
args.put("url", url);
args.put("faviconUrl", faviconUrl);
} catch (JSONException e) {
Log.w(LOGTAG, "Error building JSON favicon arguments.", e);
}
args.putString("url", url);
args.putString("faviconUrl", faviconUrl);
}
callback.sendSuccess(args.toString());
callback.sendSuccess(args);
}
}).execute();
}
@ -130,7 +126,9 @@ public final class ReadingListHelper implements BundleEventListener {
SavedReaderViewHelper rch = SavedReaderViewHelper.getSavedReaderViewHelper(context);
if (!rch.isURLCached(url)) {
GeckoAppShell.notifyObservers("Reader:AddToCache", Integer.toString(tabID));
final GeckoBundle data = new GeckoBundle(1);
data.putInt("tabID", tabID);
EventDispatcher.getInstance().dispatch("Reader:AddToCache", data);
}
}
@ -142,7 +140,9 @@ public final class ReadingListHelper implements BundleEventListener {
SavedReaderViewHelper rch = SavedReaderViewHelper.getSavedReaderViewHelper(context);
if (rch.isURLCached(url)) {
GeckoAppShell.notifyObservers("Reader:RemoveFromCache", url);
final GeckoBundle data = new GeckoBundle(1);
data.putString("url", url);
EventDispatcher.getInstance().dispatch("Reader:RemoveFromCache", data);
}
// When removing items from the cache we can probably spare ourselves the async callback

Просмотреть файл

@ -6,11 +6,12 @@
package org.mozilla.gecko.tabqueue;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
import android.app.NotificationManager;
@ -29,7 +30,6 @@ import android.view.WindowManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
@ -284,16 +284,16 @@ public class TabQueueHelper {
JSONArray jsonArray = profile.readJSONArrayFromFile(filename);
if (jsonArray.length() > 0) {
JSONObject data = new JSONObject();
try {
data.put("urls", jsonArray);
data.put("shouldNotifyTabsOpenedToJava", shouldPerformJavaScriptCallback);
GeckoAppShell.notifyObservers("Tabs:OpenMultiple", data.toString());
} catch (JSONException e) {
// Don't exit early as we perform cleanup at the end of this function.
Log.e(LOGTAG, "Error sending tab queue data", e);
final int len = jsonArray.length();
if (len > 0) {
final String[] urls = new String[len];
for (int i = 0; i < len; i++) {
urls[i] = jsonArray.optString(i);
}
final GeckoBundle data = new GeckoBundle(2);
data.putStringArray("urls", urls);
data.putBoolean("shouldNotifyTabsOpenedToJava", shouldPerformJavaScriptCallback);
EventDispatcher.getInstance().dispatch("Tabs:OpenMultiple", data);
}
try {

Просмотреть файл

@ -7,9 +7,10 @@ package org.mozilla.gecko.tabs;
import java.util.ArrayList;
import java.util.List;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.R;
import org.mozilla.gecko.util.GeckoBundle;
import android.content.Context;
import android.content.DialogInterface;
@ -85,8 +86,9 @@ public class TabHistoryFragment extends Fragment implements OnItemClickListener,
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String index = String.valueOf(toIndex - position);
GeckoAppShell.notifyObservers("Session:Navigate", index);
final GeckoBundle data = new GeckoBundle(1);
data.putInt("index", toIndex - position);
EventDispatcher.getInstance().dispatch("Session:Navigate", data);
dismiss();
}

Просмотреть файл

@ -81,7 +81,6 @@ public abstract class TabsLayout extends RecyclerView
public void hide() {
setVisibility(View.GONE);
Tabs.unregisterOnTabsChangedListener(this);
GeckoAppShell.notifyObservers("Tab:Screenshot:Cancel", "");
tabsAdapter.clear();
}

Просмотреть файл

@ -30,19 +30,21 @@ var mediaPlayerDevice = {
types: ["video/mp4", "video/webm", "application/x-mpegurl"],
extensions: ["mp4", "webm", "m3u", "m3u8"],
init: function() {
Services.obs.addObserver(this, "MediaPlayer:Added", false);
Services.obs.addObserver(this, "MediaPlayer:Changed", false);
Services.obs.addObserver(this, "MediaPlayer:Removed", false);
GlobalEventDispatcher.registerListener(this, [
"MediaPlayer:Added",
"MediaPlayer:Changed",
"MediaPlayer:Removed",
]);
},
observe: function(subject, topic, data) {
if (topic === "MediaPlayer:Added") {
let service = this.toService(JSON.parse(data));
onEvent: function(event, data, callback) {
if (event === "MediaPlayer:Added") {
let service = this.toService(data);
SimpleServiceDiscovery.addService(service);
} else if (topic === "MediaPlayer:Changed") {
let service = this.toService(JSON.parse(data));
} else if (event === "MediaPlayer:Changed") {
let service = this.toService(data);
SimpleServiceDiscovery.updateService(service);
} else if (topic === "MediaPlayer:Removed") {
SimpleServiceDiscovery.removeService(data);
} else if (event === "MediaPlayer:Removed") {
SimpleServiceDiscovery.removeService(data.id);
}
},
toService: function(display) {

Просмотреть файл

@ -13,10 +13,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPI",
var EmbedRT = {
_scopes: {},
observe: function(subject, topic, data) {
switch(topic) {
onEvent: function (event, data, callback) {
switch (event) {
case "GeckoView:ImportScript":
this.importScript(data);
this.importScript(data.scriptURL);
break;
}
},

Просмотреть файл

@ -57,9 +57,8 @@ var FeedHandler = {
}
},
observe: function fh_observe(aSubject, aTopic, aData) {
if (aTopic === "Feeds:Subscribe") {
let args = JSON.parse(aData);
onEvent: function fh_onEvent(event, args, callback) {
if (event === "Feeds:Subscribe") {
let tab = BrowserApp.getTabForId(args.tabId);
if (!tab)
return;

Просмотреть файл

@ -10,8 +10,8 @@ var Feedback = {
return this._feedbackURL = Services.urlFormatter.formatURLPref("app.feedbackURL");
},
observe: function(aMessage, aTopic, aData) {
if (aTopic !== "Feedback:Show") {
onEvent: function(event, data, callback) {
if (event !== "Feedback:Show") {
return;
}

Просмотреть файл

@ -55,17 +55,17 @@ var Reader = {
return { handled: (listener ? listener() : false) };
},
observe: function Reader_observe(aMessage, aTopic, aData) {
switch (aTopic) {
onEvent: function Reader_onEvent(event, data, callback) {
switch (event) {
case "Reader:RemoveFromCache": {
ReaderMode.removeArticleFromCache(aData).catch(e => Cu.reportError("Error removing article from cache: " + e));
ReaderMode.removeArticleFromCache(data.url).catch(e => Cu.reportError("Error removing article from cache: " + e));
break;
}
case "Reader:AddToCache": {
let tab = BrowserApp.getTabForId(aData);
let tab = BrowserApp.getTabForId(data.tabID);
if (!tab) {
throw new Error("No tab for tabID = " + aData + " when trying to save reader view article");
throw new Error("No tab for tabID = " + data.tabID + " when trying to save reader view article");
}
// If the article is coming from reader mode, we must have fetched it already.
@ -120,7 +120,7 @@ var Reader = {
type: "Reader:FaviconRequest",
url: message.data.url
}).then(data => {
message.target.messageManager.sendAsyncMessage("Reader:FaviconReturn", JSON.parse(data));
message.target.messageManager.sendAsyncMessage("Reader:FaviconReturn", data);
});
break;
}

Просмотреть файл

@ -15,7 +15,7 @@ var WebcompatReporter = {
menuItem: null,
menuItemEnabled: null,
init: function() {
Services.obs.addObserver(this, "DesktopMode:Change", false);
GlobalEventDispatcher.registerListener(this, "DesktopMode:Change");
Services.obs.addObserver(this, "chrome-document-global-created", false);
Services.obs.addObserver(this, "content-document-global-created", false);
@ -28,6 +28,16 @@ var WebcompatReporter = {
this.addMenuItem(visible);
},
onEvent: function(event, data, callback) {
if (event === "DesktopMode:Change") {
let tab = BrowserApp.getTabForId(data.tabId);
let currentURI = tab.browser.currentURI.spec;
if (data.desktopMode && this.isReportableUrl(currentURI)) {
this.reportDesktopModePrompt(tab);
}
}
},
observe: function(subject, topic, data) {
if (topic == "content-document-global-created" || topic == "chrome-document-global-created") {
let win = subject;
@ -45,13 +55,6 @@ var WebcompatReporter = {
NativeWindow.menu.update(this.menuItem, {enabled: false});
this.menuItemEnabled = false;
}
} else if (topic === "DesktopMode:Change") {
let args = JSON.parse(data);
let tab = BrowserApp.getTabForId(args.tabId);
let currentURI = tab.browser.currentURI.spec;
if (args.desktopMode && this.isReportableUrl(currentURI)) {
this.reportDesktopModePrompt(tab);
}
}
},

Просмотреть файл

@ -59,26 +59,19 @@ function init() {
} catch (ex) {}
#ifdef MOZ_UPDATER
let Updater = {
update: null,
init: function() {
Services.obs.addObserver(this, "Update:CheckResult", false);
},
observe: function(aSubject, aTopic, aData) {
if (aTopic == "Update:CheckResult") {
showUpdateMessage(aData);
}
},
};
Updater.init();
function checkForUpdates() {
showCheckingMessage();
let window = Services.wm.getMostRecentWindow("navigator:browser");
window.WindowEventDispatcher.registerListener(
function listener(event, data, callback) {
if (event === "Update:CheckResult") {
EventDispatcher.instance.unregisterListener(listener, event);
showUpdateMessage(data.result);
}
}, "Update:CheckResult");
window.WindowEventDispatcher.sendRequest({ type: "Update:Check" });
}

Просмотреть файл

@ -152,10 +152,6 @@ lazilyLoadedBrowserScripts.forEach(function (aScript) {
var lazilyLoadedObserverScripts = [
["MemoryObserver", ["memory-pressure", "Memory:Dump"], "chrome://browser/content/MemoryObserver.js"],
["ConsoleAPI", ["console-api-log-event"], "chrome://browser/content/ConsoleAPI.js"],
["FeedHandler", ["Feeds:Subscribe"], "chrome://browser/content/FeedHandler.js"],
["Feedback", ["Feedback:Show"], "chrome://browser/content/Feedback.js"],
["EmbedRT", ["GeckoView:ImportScript"], "chrome://browser/content/EmbedRT.js"],
["Reader", ["Reader:AddToCache", "Reader:RemoveFromCache"], "chrome://browser/content/Reader.js"],
];
if (AppConstants.MOZ_WEBRTC) {
@ -231,6 +227,15 @@ lazilyLoadedObserverScripts.forEach(function (aScript) {
["ActionBarHandler", WindowEventDispatcher,
["TextSelection:Get", "TextSelection:Action", "TextSelection:End"],
"chrome://browser/content/ActionBarHandler.js"],
["EmbedRT", WindowEventDispatcher,
["GeckoView:ImportScript"],
"chrome://browser/content/EmbedRT.js"],
["Feedback", GlobalEventDispatcher,
["Feedback:Show"],
"chrome://browser/content/Feedback.js"],
["FeedHandler", GlobalEventDispatcher,
["Feeds:Subscribe"],
"chrome://browser/content/FeedHandler.js"],
["FindHelper", GlobalEventDispatcher,
["FindInPage:Opened", "FindInPage:Closed"],
"chrome://browser/content/FindHelper.js"],
@ -244,6 +249,9 @@ lazilyLoadedObserverScripts.forEach(function (aScript) {
["PrintHelper", GlobalEventDispatcher,
["Print:PDF"],
"chrome://browser/content/PrintHelper.js"],
["Reader", GlobalEventDispatcher,
["Reader:AddToCache", "Reader:RemoveFromCache"],
"chrome://browser/content/Reader.js"],
].forEach(module => {
let [name, dispatcher, events, script] = module;
XPCOMUtils.defineLazyGetter(window, name, function() {
@ -383,28 +391,33 @@ var BrowserApp = {
"Tab:Selected",
"Tab:Closed",
"Browser:LoadManifest",
"Browser:Quit",
"Fonts:Reload",
"FormHistory:Init",
"FullScreen:Exit",
"Locale:OS",
"Locale:Changed",
"Passwords:Init",
"Sanitize:ClearData",
"SaveAs:PDF",
"ScrollTo:FocusedInput",
"Session:Back",
"Session:Forward",
"Session:GetHistory",
"Session:Navigate",
"Session:Reload",
"Session:Stop",
]);
Services.obs.addObserver(this, "Locale:OS", false);
Services.obs.addObserver(this, "Locale:Changed", false);
Services.obs.addObserver(this, "Session:Back", false);
Services.obs.addObserver(this, "Session:Forward", false);
Services.obs.addObserver(this, "Session:Navigate", false);
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, "ScrollTo:FocusedInput", false);
Services.obs.addObserver(this, "Sanitize:ClearData", false);
Services.obs.addObserver(this, "FullScreen:Exit", false);
Services.obs.addObserver(this, "Passwords:Init", false);
Services.obs.addObserver(this, "FormHistory:Init", false);
// Provide compatibility for add-ons like QuitNow that send "Browser:Quit"
// as an observer notification.
Services.obs.addObserver((subject, topic, data) =>
this.quit(data ? JSON.parse(data) : undefined), "Browser:Quit", false);
Services.obs.addObserver(this, "android-get-pref", false);
Services.obs.addObserver(this, "android-set-pref", false);
Services.obs.addObserver(this, "gather-telemetry", false);
Services.obs.addObserver(this, "keyword-search", false);
Services.obs.addObserver(this, "Fonts:Reload", false);
Services.obs.addObserver(this, "Vibration:Request", false);
window.addEventListener("fullscreen", function() {
@ -973,8 +986,8 @@ var BrowserApp = {
onAppUpdated: function() {
// initialize the form history and passwords databases on upgrades
Services.obs.notifyObservers(null, "FormHistory:Init", "");
Services.obs.notifyObservers(null, "Passwords:Init", "");
GlobalEventDispatcher.dispatch("FormHistory:Init", null);
GlobalEventDispatcher.dispatch("Passwords:Init", null);
if (this._startupStatus === "upgrade") {
this._migrateUI();
@ -1632,11 +1645,137 @@ var BrowserApp = {
break;
}
case "Browser:Quit":
this.quit(data);
break;
case "Fonts:Reload":
FontEnumerator.updateFontList();
break;
case "FormHistory:Init": {
// Force creation/upgrade of formhistory.sqlite
FormHistory.count({});
GlobalEventDispatcher.unregisterListener(this, event);
break;
}
case "FullScreen:Exit":
browser.contentDocument.exitFullscreen();
break;
case "Locale:OS": {
// We know the system locale. We use this for generating Accept-Language headers.
let languageTag = data.languageTag;
console.log("Locale:OS: " + languageTag);
let currentOSLocale = this.getOSLocalePref();
if (currentOSLocale == languageTag) {
break;
}
console.log("New OS locale.");
// Ensure that this choice is immediately persisted, because
// Gecko won't be told again if it forgets.
Services.prefs.setCharPref("intl.locale.os", languageTag);
Services.prefs.savePrefFile(null);
let appLocale = this.getUALocalePref();
this.computeAcceptLanguages(languageTag, appLocale);
break;
}
case "Locale:Changed": {
if (data) {
// The value provided to Locale:Changed should be a BCP47 language tag
// understood by Gecko -- for example, "es-ES" or "de".
console.log("Locale:Changed: " + data.languageTag);
// We always write a localized pref, even though sometimes the value is a char pref.
// (E.g., on desktop single-locale builds.)
this.setLocalizedPref("general.useragent.locale", data.languageTag);
} else {
// Resetting.
console.log("Switching to system locale.");
Services.prefs.clearUserPref("general.useragent.locale");
}
Services.prefs.setBoolPref("intl.locale.matchOS", !data);
// Ensure that this choice is immediately persisted, because
// Gecko won't be told again if it forgets.
Services.prefs.savePrefFile(null);
// Blow away the string cache so that future lookups get the
// correct locale.
Strings.flush();
// Make sure we use the right Accept-Language header.
let osLocale;
try {
// This should never not be set at this point, but better safe than sorry.
osLocale = Services.prefs.getCharPref("intl.locale.os");
} catch (e) {
}
this.computeAcceptLanguages(osLocale, data && data.languageTag);
break;
}
case "Passwords:Init": {
let storage = Cc["@mozilla.org/login-manager/storage/mozStorage;1"].
getService(Ci.nsILoginManagerStorage);
storage.initialize();
GlobalEventDispatcher.unregisterListener(this, event);
break;
}
case "Sanitize:ClearData":
this.sanitize(data);
break;
case "SaveAs:PDF":
this.saveAsPDF(browser);
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
this.scrollToFocusedInput(browser, false);
break;
}
case "Session:GetHistory": {
callback.onSuccess(this.getHistory(data));
break;
}
case "Session:Back":
browser.goBack();
break;
case "Session:Forward":
browser.goForward();
break;
case "Session:Navigate": {
let index = data.index;
let webNav = BrowserApp.selectedTab.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation);
let historySize = webNav.sessionHistory.count;
if (index < 0) {
index = 0;
Log.e("Browser", "Negative index truncated to zero");
} else if (index >= historySize) {
Log.e("Browser", "Incorrect index " + index + " truncated to " + historySize - 1);
index = historySize - 1;
}
browser.gotoIndex(index);
break;
}
case "Session:Reload": {
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
@ -1689,6 +1828,10 @@ var BrowserApp = {
break;
}
case "Session:Stop":
browser.stop();
break;
case "Tab:Load": {
let url = data.url;
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
@ -1754,34 +1897,6 @@ var BrowserApp = {
let browser = this.selectedBrowser;
switch (aTopic) {
case "Session:Back":
browser.goBack();
break;
case "Session:Forward":
browser.goForward();
break;
case "Session:Navigate":
let index = JSON.parse(aData);
let webNav = BrowserApp.selectedTab.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation);
let historySize = webNav.sessionHistory.count;
if (index < 0) {
index = 0;
Log.e("Browser", "Negative index truncated to zero");
} else if (index >= historySize) {
Log.e("Browser", "Incorrect index " + index + " truncated to " + historySize - 1);
index = historySize - 1;
}
browser.gotoIndex(index);
break;
case "Session:Stop":
browser.stop();
break;
case "keyword-search":
// This event refers to a search via the URL bar, not a bookmarks
// keyword search. Note that this code assumes that the user can only
@ -1801,45 +1916,6 @@ var BrowserApp = {
});
break;
case "Browser:Quit":
// Add-ons like QuitNow and CleanQuit provide aData as an empty-string ("").
// Pass undefined to invoke the methods default parms.
this.quit(aData ? JSON.parse(aData) : undefined);
break;
case "SaveAs:PDF":
this.saveAsPDF(browser);
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
this.scrollToFocusedInput(browser, false);
break;
case "Sanitize:ClearData":
this.sanitize(JSON.parse(aData));
break;
case "FullScreen:Exit":
browser.contentDocument.exitFullscreen();
break;
case "Passwords:Init": {
let storage = Cc["@mozilla.org/login-manager/storage/mozStorage;1"].
getService(Ci.nsILoginManagerStorage);
storage.initialize();
Services.obs.removeObserver(this, "Passwords:Init");
break;
}
case "FormHistory:Init": {
// Force creation/upgrade of formhistory.sqlite
FormHistory.count({});
Services.obs.removeObserver(this, "FormHistory:Init");
break;
}
case "android-get-pref": {
// These pref names are not "real" pref names. They are used in the
// setting menu, and these are passed when initializing the setting
@ -1943,66 +2019,6 @@ var BrowserApp = {
GlobalEventDispatcher.sendRequest({ type: "Telemetry:Gather" });
break;
case "Locale:OS":
// We know the system locale. We use this for generating Accept-Language headers.
console.log("Locale:OS: " + aData);
let currentOSLocale = this.getOSLocalePref();
if (currentOSLocale == aData) {
break;
}
console.log("New OS locale.");
// Ensure that this choice is immediately persisted, because
// Gecko won't be told again if it forgets.
Services.prefs.setCharPref("intl.locale.os", aData);
Services.prefs.savePrefFile(null);
let appLocale = this.getUALocalePref();
this.computeAcceptLanguages(aData, appLocale);
break;
case "Locale:Changed":
if (aData) {
// The value provided to Locale:Changed should be a BCP47 language tag
// understood by Gecko -- for example, "es-ES" or "de".
console.log("Locale:Changed: " + aData);
// We always write a localized pref, even though sometimes the value is a char pref.
// (E.g., on desktop single-locale builds.)
this.setLocalizedPref("general.useragent.locale", aData);
} else {
// Resetting.
console.log("Switching to system locale.");
Services.prefs.clearUserPref("general.useragent.locale");
}
Services.prefs.setBoolPref("intl.locale.matchOS", !aData);
// Ensure that this choice is immediately persisted, because
// Gecko won't be told again if it forgets.
Services.prefs.savePrefFile(null);
// Blow away the string cache so that future lookups get the
// correct locale.
Strings.flush();
// Make sure we use the right Accept-Language header.
let osLocale;
try {
// This should never not be set at this point, but better safe than sorry.
osLocale = Services.prefs.getCharPref("intl.locale.os");
} catch (e) {
}
this.computeAcceptLanguages(osLocale, aData);
break;
case "Fonts:Reload":
FontEnumerator.updateFontList();
break;
case "Vibration:Request":
if (aSubject instanceof Navigator) {
let navigator = aSubject;
@ -2189,8 +2205,8 @@ var NativeWindow = {
init: function() {
GlobalEventDispatcher.registerListener(this, [
"Doorhanger:Reply",
"Menu:Clicked",
]);
Services.obs.addObserver(this, "Menu:Clicked", false);
this.contextmenus.init();
},
@ -2338,13 +2354,10 @@ var NativeWindow = {
}
}
}
}
},
observe: function(aSubject, aTopic, aData) {
if (aTopic == "Menu:Clicked") {
if (this.menu._callbacks[aData])
this.menu._callbacks[aData]();
} else if (aTopic == "Menu:Clicked") {
if (this.menu._callbacks[data.item]) {
this.menu._callbacks[data.item]();
}
}
},
@ -3214,7 +3227,7 @@ var DesktopUserAgent = {
TCO_REPLACE: / Gecko.*/,
init: function ua_init() {
Services.obs.addObserver(this, "DesktopMode:Change", false);
GlobalEventDispatcher.registerListener(this, "DesktopMode:Change");
UserAgentOverrides.addComplexOverride(this.onRequest.bind(this));
// See https://developer.mozilla.org/en/Gecko_user_agent_string_reference
@ -3289,15 +3302,14 @@ var DesktopUserAgent = {
return null;
},
observe: function ua_observe(aSubject, aTopic, aData) {
if (aTopic === "DesktopMode:Change") {
let args = JSON.parse(aData);
let tab = BrowserApp.getTabForId(args.tabId);
onEvent: function ua_onEvent(event, data, callback) {
if (event === "DesktopMode:Change") {
let tab = BrowserApp.getTabForId(data.tabId);
if (tab) {
tab.reloadWithMode(args.desktopMode);
tab.reloadWithMode(data.desktopMode);
}
}
}
},
};
@ -5560,14 +5572,13 @@ var XPInstallObserver = {
var ViewportHandler = {
init: function init() {
Services.obs.addObserver(this, "Window:Resize", false);
GlobalEventDispatcher.registerListener(this, "Window:Resize");
},
observe: function(aSubject, aTopic, aData) {
if (aTopic == "Window:Resize" && aData) {
let scrollChange = JSON.parse(aData);
onEvent: function (event, data, callback) {
if (event == "Window:Resize" && data) {
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
windowUtils.setNextPaintSyncId(scrollChange.id);
windowUtils.setNextPaintSyncId(data.id);
}
}
};
@ -5752,18 +5763,20 @@ var CharacterEncoding = {
_charsets: [],
init: function init() {
Services.obs.addObserver(this, "CharEncoding:Get", false);
Services.obs.addObserver(this, "CharEncoding:Set", false);
GlobalEventDispatcher.registerListener(this, [
"CharEncoding:Get",
"CharEncoding:Set",
]);
InitLater(() => this.sendState());
},
observe: function observe(aSubject, aTopic, aData) {
switch (aTopic) {
onEvent: function onEvent(event, data, callback) {
switch (event) {
case "CharEncoding:Get":
this.getEncoding();
break;
case "CharEncoding:Set":
this.setEncoding(aData);
this.setEncoding(data.encoding);
break;
}
},
@ -6480,8 +6493,7 @@ var Experiments = {
init() {
GlobalEventDispatcher.sendRequestForResult({
type: "Experiments:GetActive"
}).then(experiments => {
let names = JSON.parse(experiments);
}).then(names => {
for (let name of names) {
switch (name) {
case this.MALWARE_DOWNLOAD_PROTECTION: {
@ -6672,10 +6684,12 @@ var Distribution = {
_preferencesJSON: null,
init: function dc_init() {
Services.obs.addObserver(this, "Distribution:Changed", false);
Services.obs.addObserver(this, "Distribution:Set", false);
GlobalEventDispatcher.registerListener(this, [
"Campaign:Set",
"Distribution:Changed",
"Distribution:Set",
]);
Services.obs.addObserver(this, "prefservice:after-app-defaults", false);
Services.obs.addObserver(this, "Campaign:Set", false);
// Look for file outside the APK:
// /data/data/org.mozilla.xxx/distribution.json
@ -6684,8 +6698,23 @@ var Distribution = {
this.readJSON(this._file, this.update);
},
observe: function dc_observe(aSubject, aTopic, aData) {
switch (aTopic) {
onEvent: function dc_onEvent(event, data, callback) {
switch (event) {
case "Campaign:Set": {
// Update the prefs for this session
try {
this.update(data);
} catch (ex) {
Cu.reportError("Distribution: Could not parse JSON: " + ex);
return;
}
// Asynchronously copy the data to the file.
let array = new TextEncoder().encode(JSON.stringify(data));
OS.File.writeAtomic(this._file.path, array, { tmpPath: this._file.path + ".tmp" });
break;
}
case "Distribution:Changed":
// Re-init the search service.
try {
@ -6696,9 +6725,9 @@ var Distribution = {
// Fall through.
case "Distribution:Set":
if (aData) {
if (data) {
try {
this._preferencesJSON = JSON.parse(aData);
this._preferencesJSON = JSON.parse(data.preferences);
} catch (e) {
console.log("Invalid distribution JSON.");
}
@ -6707,25 +6736,14 @@ var Distribution = {
Services.prefs.QueryInterface(Ci.nsIObserver).observe(null, "reload-default-prefs", null);
this.installDistroAddons();
break;
}
},
observe: function dc_observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "prefservice:after-app-defaults":
this.getPrefs();
break;
case "Campaign:Set": {
// Update the prefs for this session
try {
this.update(JSON.parse(aData));
} catch (ex) {
Cu.reportError("Distribution: Could not parse JSON: " + ex);
return;
}
// Asynchronously copy the data to the file.
let array = new TextEncoder().encode(aData);
OS.File.writeAtomic(this._file.path, array, { tmpPath: this._file.path + ".tmp" });
break;
}
}
},
@ -6903,8 +6921,10 @@ var Tabs = {
Services.obs.addObserver(this, "memory-pressure", false);
}
// Watch for opportunities to pre-connect to high probability targets.
Services.obs.addObserver(this, "Session:Prefetch", false);
GlobalEventDispatcher.registerListener(this, [
// Watch for opportunities to pre-connect to high probability targets.
"Session:Prefetch",
]);
// Track the network connection so we can efficiently use the cache
// for possible offline rendering.
@ -6916,6 +6936,24 @@ var Tabs = {
BrowserApp.deck.addEventListener("TabOpen", this);
},
onEvent: function(event, data, callback) {
switch (event) {
case "Session:Prefetch":
if (!data.url) {
break;
}
try {
let uri = Services.io.newURI(data.url);
if (uri && !this._domains.has(uri.host)) {
Services.io.QueryInterface(Ci.nsISpeculativeConnect).speculativeConnect2(
uri, BrowserApp.selectedBrowser.contentDocument.nodePrincipal, null);
this._domains.add(uri.host);
}
} catch (e) {}
break;
}
},
observe: function(aSubject, aTopic, aData) {
switch (aTopic) {
case "memory-pressure":
@ -6929,21 +6967,6 @@ var Tabs = {
this.expireLruTab();
}
break;
case "Session:Prefetch":
if (aData) {
try {
let uri = Services.io.newURI(aData);
if (uri && !this._domains.has(uri.host)) {
Services.io.QueryInterface(Ci.nsISpeculativeConnect).speculativeConnect2(uri,
BrowserApp.selectedBrowser
.contentDocument
.nodePrincipal,
null);
this._domains.add(uri.host);
}
} catch (e) {}
}
break;
case "network:link-status-changed":
if (["down", "unknown", "up"].indexOf(aData) == -1) {
return;

Просмотреть файл

@ -160,10 +160,88 @@ SessionStore.prototype = {
this._lastClosedTabIndex = -1;
},
onEvent: function ss_onEvent(event, data, callback) {
switch (event) {
case "ClosedTabs:StartNotifications":
this._notifyClosedTabs = true;
log("ClosedTabs:StartNotifications");
this._sendClosedTabsToJava(Services.wm.getMostRecentWindow("navigator:browser"));
break;
case "ClosedTabs:StopNotifications":
this._notifyClosedTabs = false;
log("ClosedTabs:StopNotifications");
break;
case "Session:Restore": {
EventDispatcher.instance.unregisterListener(this, "Session:Restore");
if (data) {
// Be ready to handle any restore failures by making sure we have a valid tab opened
let window = Services.wm.getMostRecentWindow("navigator:browser");
let restoreCleanup = (function (aSubject, aTopic, aData) {
Services.obs.removeObserver(restoreCleanup, "sessionstore-windows-restored");
if (window.BrowserApp.tabs.length == 0) {
window.BrowserApp.addTab("about:home", {
selected: true
});
}
// Normally, _restoreWindow() will have set this to true already,
// but we want to make sure it's set even in case of a restore failure.
this._startupRestoreFinished = true;
log("startupRestoreFinished = true (through notification)");
}).bind(this);
Services.obs.addObserver(restoreCleanup, "sessionstore-windows-restored", false);
// Do a restore, triggered by Java
this.restoreLastSession(data.sessionString);
} else {
// Not doing a restore; just send restore message
this._startupRestoreFinished = true;
log("startupRestoreFinished = true");
Services.obs.notifyObservers(null, "sessionstore-windows-restored", "");
}
break;
}
case "Session:RestoreRecentTabs":
this._restoreTabs(data);
break;
case "Tab:KeepZombified": {
if (data.nextSelectedTabId >= 0) {
this._keepAsZombieTabId = data.nextSelectedTabId;
log("Tab:KeepZombified " + data.nextSelectedTabId);
}
break;
}
case "Tabs:OpenMultiple": {
this._openTabs(data);
if (data.shouldNotifyTabsOpenedToJava) {
let window = Services.wm.getMostRecentWindow("navigator:browser");
window.WindowEventDispatcher.sendRequest({
type: "Tabs:TabsOpened"
});
}
break;
}
}
},
observe: function ss_observe(aSubject, aTopic, aData) {
let observerService = Services.obs;
switch (aTopic) {
case "app-startup":
EventDispatcher.instance.registerListener(this, [
"ClosedTabs:StartNotifications",
"ClosedTabs:StopNotifications",
"Session:Restore",
"Session:RestoreRecentTabs",
"Tab:KeepZombified",
"Tabs:OpenMultiple",
]);
observerService.addObserver(this, "final-ui-startup", true);
observerService.addObserver(this, "domwindowopened", true);
observerService.addObserver(this, "domwindowclosed", true);
@ -172,17 +250,11 @@ SessionStore.prototype = {
observerService.addObserver(this, "quit-application-requested", true);
observerService.addObserver(this, "quit-application-proceeding", true);
observerService.addObserver(this, "quit-application", true);
observerService.addObserver(this, "Session:Restore", true);
observerService.addObserver(this, "Session:NotifyLocationChange", true);
observerService.addObserver(this, "Content:HistoryChange", true);
observerService.addObserver(this, "Tab:KeepZombified", true);
observerService.addObserver(this, "application-background", true);
observerService.addObserver(this, "application-foreground", true);
observerService.addObserver(this, "ClosedTabs:StartNotifications", true);
observerService.addObserver(this, "ClosedTabs:StopNotifications", true);
observerService.addObserver(this, "last-pb-context-exited", true);
observerService.addObserver(this, "Session:RestoreRecentTabs", true);
observerService.addObserver(this, "Tabs:OpenMultiple", true);
break;
case "final-ui-startup":
observerService.removeObserver(this, "final-ui-startup");
@ -274,39 +346,6 @@ SessionStore.prototype = {
}
}
break;
case "Session:Restore": {
Services.obs.removeObserver(this, "Session:Restore");
if (aData) {
// Be ready to handle any restore failures by making sure we have a valid tab opened
let window = Services.wm.getMostRecentWindow("navigator:browser");
let restoreCleanup = {
observe: function (aSubject, aTopic, aData) {
Services.obs.removeObserver(restoreCleanup, "sessionstore-windows-restored");
if (window.BrowserApp.tabs.length == 0) {
window.BrowserApp.addTab("about:home", {
selected: true
});
}
// Normally, _restoreWindow() will have set this to true already,
// but we want to make sure it's set even in case of a restore failure.
this._startupRestoreFinished = true;
log("startupRestoreFinished = true (through notification)");
}.bind(this)
};
Services.obs.addObserver(restoreCleanup, "sessionstore-windows-restored", false);
// Do a restore, triggered by Java
let data = JSON.parse(aData);
this.restoreLastSession(data.sessionString);
} else {
// Not doing a restore; just send restore message
this._startupRestoreFinished = true;
log("startupRestoreFinished = true");
Services.obs.notifyObservers(null, "sessionstore-windows-restored", "");
}
break;
}
case "Session:NotifyLocationChange": {
let browser = aSubject;
@ -342,26 +381,6 @@ SessionStore.prototype = {
}
break;
}
case "Tabs:OpenMultiple": {
let data = JSON.parse(aData);
this._openTabs(data);
if (data.shouldNotifyTabsOpenedToJava) {
let window = Services.wm.getMostRecentWindow("navigator:browser");
window.WindowEventDispatcher.sendRequest({
type: "Tabs:TabsOpened"
});
}
break;
}
case "Tab:KeepZombified": {
if (aData >= 0) {
this._keepAsZombieTabId = aData;
log("Tab:KeepZombified " + aData);
}
break;
}
case "application-background":
// We receive this notification when Android's onPause callback is
// executed. After onPause, the application may be terminated at any
@ -390,15 +409,6 @@ SessionStore.prototype = {
this.restoreZombieTab(tab);
}
break;
case "ClosedTabs:StartNotifications":
this._notifyClosedTabs = true;
log("ClosedTabs:StartNotifications");
this._sendClosedTabsToJava(Services.wm.getMostRecentWindow("navigator:browser"));
break;
case "ClosedTabs:StopNotifications":
this._notifyClosedTabs = false;
log("ClosedTabs:StopNotifications");
break;
case "last-pb-context-exited":
// Clear private closed tab data when we leave private browsing.
for (let window of Object.values(this._windows)) {
@ -406,11 +416,6 @@ SessionStore.prototype = {
}
this._lastClosedTabIndex = -1;
break;
case "Session:RestoreRecentTabs": {
let data = JSON.parse(aData);
this._restoreTabs(data);
break;
}
}
},

Просмотреть файл

@ -95,11 +95,6 @@ public class BaseGeckoInterface implements GeckoAppShell.GeckoInterface {
return null;
}
@Override
public void notifyCheckUpdateResult(String result) {
GeckoAppShell.notifyObservers("Update:CheckResult", result);
}
// Bug 908792: Implement this
@Override
public void invalidateOptionsMenu() {}

Просмотреть файл

@ -234,7 +234,9 @@ public final class EventDispatcher extends JNIObject {
}
}
dispatchToThreads(type, message, /* callback */ callback);
if (!dispatchToThreads(type, message, /* callback */ callback)) {
Log.w(LOGTAG, "No listener for " + type);
}
}
@WrapForJNI(calledFrom = "gecko")

Просмотреть файл

@ -7,6 +7,7 @@ package org.mozilla.gecko;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UIAsyncTask;
@ -46,7 +47,6 @@ public class GeckoAccessibility {
new UIAsyncTask.WithoutParams<Void>(ThreadUtils.getBackgroundHandler()) {
@Override
public Void doInBackground() {
JSONObject ret = new JSONObject();
sEnabled = false;
AccessibilityManager accessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
@ -55,13 +55,9 @@ public class GeckoAccessibility {
sSelfBrailleClient = new SelfBrailleClient(context, false);
}
try {
ret.put("enabled", sEnabled);
} catch (Exception ex) {
Log.e(LOGTAG, "Error building JSON arguments for Accessibility:Settings:", ex);
}
GeckoAppShell.notifyObservers("Accessibility:Settings", ret.toString());
final GeckoBundle ret = new GeckoBundle(1);
ret.putBoolean("enabled", sEnabled);
EventDispatcher.getInstance().dispatch("Accessibility:Settings", ret);
return null;
}
@ -264,8 +260,11 @@ public class GeckoAccessibility {
}
public static void onLayerViewFocusChanged(boolean gainFocus) {
if (sEnabled)
GeckoAppShell.notifyObservers("Accessibility:Focus", gainFocus ? "true" : "false");
if (sEnabled) {
final GeckoBundle data = new GeckoBundle(1);
data.putBoolean("gainFocus", gainFocus);
EventDispatcher.getInstance().dispatch("Accessibility:Focus", data);
}
}
public static class GeckoAccessibilityDelegate extends View.AccessibilityDelegate {
@ -327,34 +326,34 @@ public class GeckoAccessibility {
if (virtualViewId == VIRTUAL_CURSOR_POSITION && sHoverEnter != null) {
GeckoAccessibility.sendAccessibilityEvent(sHoverEnter, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
} else {
GeckoAppShell.notifyObservers("Accessibility:Focus", "true");
final GeckoBundle data = new GeckoBundle(1);
data.putBoolean("gainFocus", true);
EventDispatcher.getInstance().dispatch("Accessibility:Focus", data);
}
return true;
} else if (action == AccessibilityNodeInfo.ACTION_CLICK && virtualViewId == VIRTUAL_CURSOR_POSITION) {
GeckoAppShell.notifyObservers("Accessibility:ActivateObject", null);
EventDispatcher.getInstance().dispatch("Accessibility:ActivateObject", null);
return true;
} else if (action == AccessibilityNodeInfo.ACTION_LONG_CLICK && virtualViewId == VIRTUAL_CURSOR_POSITION) {
GeckoAppShell.notifyObservers("Accessibility:LongPress", null);
EventDispatcher.getInstance().dispatch("Accessibility:LongPress", null);
return true;
} else if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD && virtualViewId == VIRTUAL_CURSOR_POSITION) {
GeckoAppShell.notifyObservers("Accessibility:ScrollForward", null);
EventDispatcher.getInstance().dispatch("Accessibility:ScrollForward", null);
return true;
} else if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD && virtualViewId == VIRTUAL_CURSOR_POSITION) {
GeckoAppShell.notifyObservers("Accessibility:ScrollBackward", null);
EventDispatcher.getInstance().dispatch("Accessibility:ScrollBackward", null);
return true;
} else if (action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT && virtualViewId == VIRTUAL_CURSOR_POSITION) {
String traversalRule = "";
} else if ((action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT ||
action == AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT) && virtualViewId == VIRTUAL_CURSOR_POSITION) {
final GeckoBundle data;
if (arguments != null) {
traversalRule = arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
data = new GeckoBundle(1);
data.putString("rule", arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING));
} else {
data = null;
}
GeckoAppShell.notifyObservers("Accessibility:NextObject", traversalRule);
return true;
} else if (action == AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT && virtualViewId == VIRTUAL_CURSOR_POSITION) {
String traversalRule = "";
if (arguments != null) {
traversalRule = arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
}
GeckoAppShell.notifyObservers("Accessibility:PreviousObject", traversalRule);
EventDispatcher.getInstance().dispatch(action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT ?
"Accessibility:NextObject" : "Accessibility:PreviousObject", data);
return true;
} else if (action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY &&
virtualViewId == VIRTUAL_CURSOR_POSITION) {
@ -368,36 +367,24 @@ public class GeckoAccessibility {
int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
if (granularity <= BRAILLE_CLICK_BASE_INDEX) {
int keyIndex = BRAILLE_CLICK_BASE_INDEX - granularity;
JSONObject activationData = new JSONObject();
try {
activationData.put("keyIndex", keyIndex);
} catch (JSONException e) {
return true;
}
GeckoAppShell.notifyObservers("Accessibility:ActivateObject", activationData.toString());
final GeckoBundle data = new GeckoBundle(1);
data.putInt("keyIndex", keyIndex);
EventDispatcher.getInstance().dispatch("Accessibility:ActivateObject", data);
} else if (granularity > 0) {
JSONObject movementData = new JSONObject();
try {
movementData.put("direction", "Next");
movementData.put("granularity", granularity);
} catch (JSONException e) {
return true;
}
GeckoAppShell.notifyObservers("Accessibility:MoveByGranularity", movementData.toString());
final GeckoBundle data = new GeckoBundle(2);
data.putString("direction", "Next");
data.putInt("granularity", granularity);
EventDispatcher.getInstance().dispatch("Accessibility:MoveByGranularity", data);
}
return true;
} else if (action == AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY &&
virtualViewId == VIRTUAL_CURSOR_POSITION) {
JSONObject movementData = new JSONObject();
int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
try {
movementData.put("direction", "Previous");
movementData.put("granularity", granularity);
} catch (JSONException e) {
return true;
}
final GeckoBundle data = new GeckoBundle(2);
data.putString("direction", "Previous");
data.putInt("granularity", granularity);
if (granularity > 0) {
GeckoAppShell.notifyObservers("Accessibility:MoveByGranularity", movementData.toString());
EventDispatcher.getInstance().dispatch("Accessibility:MoveByGranularity", data);
}
return true;
}

Просмотреть файл

@ -1725,7 +1725,6 @@ public class GeckoAppShell
public void notifyWakeLockChanged(String topic, String state);
public boolean areTabsShown();
public AbsoluteLayout getPluginContainer();
public void notifyCheckUpdateResult(String result);
public void invalidateOptionsMenu();
public boolean isForegrounded();
@ -1992,7 +1991,7 @@ public class GeckoAppShell
if (imeIsEnabled && !sImeWasEnabledOnLastResize) {
// The IME just came up after not being up, so let's scroll
// to the focused input.
notifyObservers("ScrollTo:FocusedInput", "");
EventDispatcher.getInstance().dispatch("ScrollTo:FocusedInput", null);
}
sImeWasEnabledOnLastResize = imeIsEnabled;
}

Просмотреть файл

@ -8,8 +8,6 @@ package org.mozilla.gecko;
import java.util.Set;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.annotation.ReflectionTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.LayerView;
@ -413,7 +411,9 @@ public class GeckoView extends LayerView
public void importScript(final String url) {
if (url.startsWith("resource://android/assets/")) {
GeckoAppShell.notifyObservers("GeckoView:ImportScript", url);
final GeckoBundle data = new GeckoBundle(1);
data.putString("scriptURL", url);
getEventDispatcher().dispatch("GeckoView:ImportScript", data);
return;
}

Просмотреть файл

@ -7,9 +7,11 @@ package org.mozilla.gecko.gfx;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.gfx.LayerView.DrawListener;
import org.mozilla.gecko.util.FloatUtils;
import org.mozilla.gecko.util.GeckoBundle;
import android.content.Context;
import android.graphics.Color;
@ -21,7 +23,6 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.view.InputDevice;
import android.view.MotionEvent;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
@ -231,25 +232,22 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
mScreenSize.width, mScreenSize.height);
}
String json = "";
try {
if (scrollChange != null) {
int id = ++sPaintSyncId;
if (id == 0) {
// never use 0 as that is the default value for "this is not
// a special transaction"
id = ++sPaintSyncId;
}
JSONObject jsonObj = new JSONObject();
jsonObj.put("x", scrollChange.x / mViewportMetrics.zoomFactor);
jsonObj.put("y", scrollChange.y / mViewportMetrics.zoomFactor);
jsonObj.put("id", id);
json = jsonObj.toString();
final GeckoBundle data;
if (scrollChange != null) {
int id = ++sPaintSyncId;
if (id == 0) {
// never use 0 as that is the default value for "this is not
// a special transaction"
id = ++sPaintSyncId;
}
} catch (Exception e) {
Log.e(LOGTAG, "Unable to convert point to JSON", e);
data = new GeckoBundle(3);
data.putDouble("x", scrollChange.x / mViewportMetrics.zoomFactor);
data.putDouble("y", scrollChange.y / mViewportMetrics.zoomFactor);
data.putInt("id", id);
} else {
data = null;
}
GeckoAppShell.notifyObservers("Window:Resize", json);
EventDispatcher.getInstance().dispatch("Window:Resize", data);
}
/**

Просмотреть файл

@ -6,15 +6,10 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
this.EXPORTED_SYMBOLS = ["Notifications"];
function log(msg) {
// Services.console.logStringMessage(msg);
}
var _notificationsMap = {};
var _handlersMap = {};
@ -202,10 +197,7 @@ var Notifications = {
notification.cancel();
},
observe: function notif_observe(aSubject, aTopic, aData) {
Services.console.logStringMessage(aTopic + " " + aData);
let data = JSON.parse(aData);
onEvent: function notif_onEvent(event, data, callback) {
let id = data.id;
let handlerKey = data.handlerKey;
let cookie = data.cookie ? JSON.parse(data.cookie) : undefined;
@ -255,4 +247,4 @@ var Notifications = {
}
};
Services.obs.addObserver(Notifications, "Notification:Event", false);
EventDispatcher.instance.registerListener(Notifications, "Notification:Event");

Просмотреть файл

@ -123,7 +123,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1044556
is(tabTest.browser.currentURI.spec, "about:blank", "Test tab is zombified.");
// Tell the session store that it shouldn't restore that tab on selecting
observerService.notifyObservers(null, "Tab:KeepZombified", tabTest.id);
EventDispatcher.instance.dispatch("Tab:KeepZombified", {nextSelectedTabId: tabTest.id});
// Switch back to the test tab and check that it remains zombified
BrowserApp.selectTab(tabTest);
@ -154,7 +154,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1044556
is(tabTest.browser.currentURI.spec, "about:blank", "Test tab is zombified.");
// Tell the session store that it shouldn't restore that tab on selecting
observerService.notifyObservers(null, "Tab:KeepZombified", tabTest.id);
EventDispatcher.instance.dispatch("Tab:KeepZombified", {nextSelectedTabId: tabTest.id});
// Switch back to the test tab and check that it remains zombified
BrowserApp.selectTab(tabTest);

Просмотреть файл

@ -29,14 +29,11 @@ public class testAndroidCastDeviceProvider extends JavascriptTest implements Bun
GeckoAppShell.notifyObservers("presentation-view-ready", "chromecast");
} else if ("AndroidCastDevice:SyncDevice".equals(event)) {
final JSONObject json = new JSONObject();
try {
json.put("uuid", "existed-chromecast");
json.put("friendlyName", "existed-chromecast");
json.put("type", "chromecast");
} catch (JSONException ex) {
}
GeckoAppShell.notifyObservers("AndroidCastDevice:Added", json.toString());
final GeckoBundle data = new GeckoBundle(3);
data.putString("uuid", "existed-chromecast");
data.putString("friendlyName", "existed-chromecast");
data.putString("type", "chromecast");
EventDispatcher.getInstance().dispatch("AndroidCastDevice:Added", data);
}
}

Просмотреть файл

@ -10,7 +10,7 @@
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
// event name
@ -162,25 +162,25 @@ function deviceManagement() {
listener.reset();
ok(listener.count() == 1, "There should be one device in device manager after sync device.");
// Remove the device.
Services.obs.notifyObservers(null, TOPIC_ANDROID_CAST_DEVICE_REMOVED, "existed-chromecast");
EventDispatcher.instance.dispatch(TOPIC_ANDROID_CAST_DEVICE_REMOVED, {id: "existed-chromecast"});
return listener.isRemoveDeviceCalled;
}).then(() => {
listener.reset();
ok(listener.count() == 0, "There should be no any device after the device is removed.");
// Add the device.
Services.obs.notifyObservers(null, TOPIC_ANDROID_CAST_DEVICE_ADDED, JSON.stringify(device));
EventDispatcher.instance.dispatch(TOPIC_ANDROID_CAST_DEVICE_ADDED, device);
return listener.isAddDeviceCalled;
}).then(() => {
listener.reset();
ok(listener.count() == 1, "There should be only one device in device manager.");
// Add the same device, and it should trigger updateDevice.
Services.obs.notifyObservers(null, TOPIC_ANDROID_CAST_DEVICE_ADDED, JSON.stringify(device));
EventDispatcher.instance.dispatch(TOPIC_ANDROID_CAST_DEVICE_ADDED, device);
return listener.isUpdateDeviceCalled;
}).then(() => {
listener.reset();
ok(listener.count() == 1, "There should still only one device in device manager.");
// Remove the device.
Services.obs.notifyObservers(null, TOPIC_ANDROID_CAST_DEVICE_REMOVED, device.uuid);
EventDispatcher.instance.dispatch(TOPIC_ANDROID_CAST_DEVICE_REMOVED, {id: device.uuid});
return listener.isRemoveDeviceCalled;
}).then(() => {
listener.reset();
@ -224,7 +224,7 @@ function presentationLaunchAndTerminate() {
};
// Add and get the device.
Services.obs.notifyObservers(null, TOPIC_ANDROID_CAST_DEVICE_ADDED, JSON.stringify(device));
EventDispatcher.instance.dispatch(TOPIC_ANDROID_CAST_DEVICE_ADDED, device);
let presentationDevice = listener.getDevice(device.uuid).QueryInterface(Ci.nsIPresentationDevice);
ok(presentationDevice != null, "It should have nsIPresentationDevice interface.");

Просмотреть файл

@ -714,7 +714,7 @@ EventDispatcher::DispatchOnGecko(ListenersList* list, const nsAString& aEvent,
}
const nsresult rv = list->listeners[i]->OnEvent(
aEvent, aData, aCallback);
NS_ENSURE_SUCCESS(rv, rv);
Unused << NS_WARN_IF(NS_FAILED(rv));
}
return NS_OK;
}