author | Kartikaya Gupta <kgupta@mozilla.com> |
Wed, 23 Jan 2013 09:38:57 -0500 | |
changeset 119619 | a2cc396069a2a564e99f71fd7a7acfe48bebb34f |
parent 119618 | 594b9c2a8ccc353b9708f1d04f59daea512c92fc |
child 119620 | 9523a36fc9188ca1c2287da2e1829ec51855d9a2 |
push id | 21778 |
push user | kgupta@mozilla.com |
push date | Wed, 23 Jan 2013 14:39:27 +0000 |
treeherder | mozilla-inbound@a2cc396069a2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | cpeterson |
bugs | 832987 |
milestone | 21.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/mobile/android/base/BrowserApp.java +++ b/mobile/android/base/BrowserApp.java @@ -966,17 +966,17 @@ abstract public class BrowserApp extends }); } @Override public boolean onPrepareOptionsMenu(Menu aMenu) { if (aMenu == null) return false; - if (!checkLaunchState(LaunchState.GeckoRunning)) + if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) aMenu.findItem(R.id.settings).setEnabled(false); Tab tab = Tabs.getInstance().getSelectedTab(); MenuItem bookmark = aMenu.findItem(R.id.bookmark); MenuItem forward = aMenu.findItem(R.id.forward); MenuItem share = aMenu.findItem(R.id.share); MenuItem saveAsPDF = aMenu.findItem(R.id.save_as_pdf); MenuItem charEncoding = aMenu.findItem(R.id.char_encoding);
--- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -182,47 +182,20 @@ abstract public class GeckoApp protected int mRestoreMode = RESTORE_NONE; protected boolean mInitialized = false; private Telemetry.Timer mJavaUiStartupTimer; private Telemetry.Timer mGeckoReadyStartupTimer; private String mPrivateBrowsingSession; - public enum LaunchState {Launching, WaitForDebugger, - Launched, GeckoRunning, GeckoExiting}; - private static LaunchState sLaunchState = LaunchState.Launching; - abstract public int getLayout(); abstract public boolean hasTabsSideBar(); abstract protected String getDefaultProfileName(); - public static boolean checkLaunchState(LaunchState checkState) { - synchronized(sLaunchState) { - return sLaunchState == checkState; - } - } - - static void setLaunchState(LaunchState setState) { - synchronized(sLaunchState) { - sLaunchState = setState; - } - } - - // if mLaunchState is equal to checkState this sets mLaunchState to setState - // and return true. Otherwise we return false. - static boolean checkAndSetLaunchState(LaunchState checkState, LaunchState setState) { - synchronized(sLaunchState) { - if (sLaunchState != checkState) - return false; - sLaunchState = setState; - return true; - } - } - void toggleChrome(final boolean aShow) { } void focusChrome() { } public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) { // When a tab is closed, it is always unselected first. // When a tab is unselected, another tab is always selected first. switch(msg) { @@ -569,23 +542,20 @@ abstract public class GeckoApp return super.onMenuOpened(featureId, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.quit: - synchronized(sLaunchState) { - if (sLaunchState == LaunchState.GeckoRunning) - GeckoAppShell.notifyGeckoOfEvent( - GeckoEvent.createBroadcastEvent("Browser:Quit", null)); - else - System.exit(0); - sLaunchState = LaunchState.GeckoExiting; + if (GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.GeckoRunning, GeckoThread.LaunchState.GeckoExiting)) { + GeckoAppShell.notifyGeckoOfEvent(GeckoEvent.createBroadcastEvent("Browser:Quit", null)); + } else { + System.exit(0); } return true; default: return super.onOptionsItemSelected(item); } } @Override @@ -854,18 +824,16 @@ abstract public class GeckoApp final String uri = message.getString("uri"); final String title = message.getString("title"); handleLoadError(tabId, uri, title); } else if (event.equals("Content:PageShow")) { final int tabId = message.getInt("tabID"); handlePageShow(tabId); } else if (event.equals("Gecko:Ready")) { mGeckoReadyStartupTimer.stop(); - setLaunchState(GeckoApp.LaunchState.GeckoRunning); - GeckoAppShell.sendPendingEventsToGecko(); connectGeckoLayerClient(); } else if (event.equals("ToggleChrome:Hide")) { toggleChrome(false); } else if (event.equals("ToggleChrome:Show")) { toggleChrome(true); } else if (event.equals("ToggleChrome:Focus")) { focusChrome(); } else if (event.equals("DOMFullScreen:Start")) { @@ -1765,23 +1733,23 @@ abstract public class GeckoApp } Telemetry.HistogramAdd("FENNEC_STARTUP_GECKOAPP_ACTION", startupAction.ordinal()); if (!mIsRestoringActivity) { sGeckoThread = new GeckoThread(intent, passedUri); } if (!ACTION_DEBUG.equals(action) && - checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched)) { + GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.Launched)) { sGeckoThread.start(); } else if (ACTION_DEBUG.equals(action) && - checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitForDebugger)) { + GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.WaitForDebugger)) { mMainHandler.postDelayed(new Runnable() { public void run() { - setLaunchState(LaunchState.Launching); + GeckoThread.setLaunchState(GeckoThread.LaunchState.Launching); sGeckoThread.start(); } }, 1000 * 5 /* 5 seconds */); } //register for events registerEventListener("DOMContentLoaded"); registerEventListener("DOMTitleChanged"); @@ -1868,24 +1836,24 @@ abstract public class GeckoApp XXXX see bug 635342 We want to disable this code if possible. It is about 145ms in runtime SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); String localeCode = settings.getString(getPackageName() + ".locale", ""); if (localeCode != null && localeCode.length() > 0) GeckoAppShell.setSelectedLocale(localeCode); */ - if (!checkLaunchState(LaunchState.Launched)) { + if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.Launched)) { return; } } }, 50); if (mIsRestoringActivity) { - setLaunchState(GeckoApp.LaunchState.GeckoRunning); + GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoRunning); Tab selectedTab = Tabs.getInstance().getSelectedTab(); if (selectedTab != null) Tabs.getInstance().notifyListeners(selectedTab, Tabs.TabEvents.SELECTED); connectGeckoLayerClient(); GeckoAppShell.setLayerClient(mLayerView.getLayerClient()); GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Viewport:Flush", null)); } @@ -2038,17 +2006,17 @@ abstract public class GeckoApp new CopyOnWriteArrayList<String>(kRedirectWhiteListArray); private boolean isHostOnRedirectWhitelist(String host) { return kRedirectWhiteList.contains(host); } @Override protected void onNewIntent(Intent intent) { - if (checkLaunchState(LaunchState.GeckoExiting)) { + if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoExiting)) { // We're exiting and shouldn't try to do anything else just incase // we're hung for some reason we'll force the process to exit System.exit(0); return; } // if we were previously OOM killed, we can end up here when launching // from external shortcuts, so set this as the intent for initialization @@ -2056,17 +2024,17 @@ abstract public class GeckoApp setIntent(intent); return; } // don't perform any actions if launching from recent apps if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) return; - if (checkLaunchState(LaunchState.Launched)) { + if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.Launched)) { Uri data = intent.getData(); Bundle bundle = intent.getExtras(); // if the intent has data (i.e. a URI to be opened) and the scheme // is either http, we'll prefetch it, which means warming // up the radio and DNS cache by connecting and parsing the redirect // if the return code is between 300 and 400 if (data != null && "http".equals(data.getScheme()) &&
--- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -579,17 +579,17 @@ public class GeckoAppShell GeckoEvent e = gPendingEvents.removeFirst(); notifyGeckoOfEvent(e); } } catch (NoSuchElementException e) {} } /* This method is referenced by Robocop via reflection. */ public static void sendEventToGecko(GeckoEvent e) { - if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) { + if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { notifyGeckoOfEvent(e); } else { gPendingEvents.addLast(e); } } public static void sendEventToGeckoSync(GeckoEvent e) { sendEventToGecko(e); @@ -787,18 +787,18 @@ public class GeckoAppShell } public static void returnIMEQueryResult(String result, int selectionStart, int selectionLength) { // This method may be called from JNI to report Gecko's current selection indexes, but // Native Fennec doesn't care because the Java code already knows the selection indexes. } static void onXreExit() { - // mLaunchState can only be Launched or GeckoRunning at this point - GeckoApp.setLaunchState(GeckoApp.LaunchState.GeckoExiting); + // The launch state can only be Launched or GeckoRunning at this point + GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoExiting); if (gRestartScheduled) { GeckoApp.mAppContext.doRestart(); } else { GeckoApp.mAppContext.finish(); } Log.d(LOGTAG, "Killing via System.exit()"); System.exit(0);
--- a/mobile/android/base/GeckoApplication.java +++ b/mobile/android/base/GeckoApplication.java @@ -36,17 +36,17 @@ public class GeckoApplication extends Ap mInBackground = true; GeckoAppShell.sendEventToGecko(GeckoEvent.createPauseEvent(true)); GeckoConnectivityReceiver.getInstance().stop(); GeckoNetworkManager.getInstance().stop(); } protected void onActivityResume(GeckoActivity activity) { - if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) + if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) GeckoAppShell.sendEventToGecko(GeckoEvent.createResumeEvent(true)); GeckoConnectivityReceiver.getInstance().start(); GeckoNetworkManager.getInstance().start(); mInBackground = false; } public boolean isApplicationInBackground() {
--- a/mobile/android/base/GeckoConnectivityReceiver.java +++ b/mobile/android/base/GeckoConnectivityReceiver.java @@ -70,13 +70,13 @@ public class GeckoConnectivityReceiver e if (info == null) { status = LINK_DATA_UNKNOWN; } else if (!info.isConnected()) { status = LINK_DATA_DOWN; } else { status = LINK_DATA_UP; } - if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) { + if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { GeckoAppShell.onChangeNetworkLinkStatus(status); } } }
--- a/mobile/android/base/GeckoThread.java +++ b/mobile/android/base/GeckoThread.java @@ -1,35 +1,49 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko; import org.mozilla.gecko.gfx.GfxInfoThread; +import org.mozilla.gecko.util.GeckoEventListener; + +import org.json.JSONObject; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.os.SystemClock; import android.util.Log; import java.util.Locale; -public class GeckoThread extends Thread { +public class GeckoThread extends Thread implements GeckoEventListener { private static final String LOGTAG = "GeckoThread"; - Intent mIntent; - String mUri; + public enum LaunchState { + Launching, + WaitForDebugger, + Launched, + GeckoRunning, + GeckoExiting + }; + + private static LaunchState sLaunchState = LaunchState.Launching; + + private final Intent mIntent; + private final String mUri; GeckoThread(Intent intent, String uri) { mIntent = intent; mUri = uri; setName("Gecko"); + GeckoAppShell.getEventDispatcher().registerEventListener("Gecko:Ready", this); } public void run() { // Here we start the GfxInfo thread, which will query OpenGL // system information for Gecko. This must be done early enough that the data will be // ready by the time it's needed to initialize the LayerManager (it takes about 100 ms // to obtain). Doing it here seems to have no negative effect on startup time. See bug 766251. @@ -74,9 +88,42 @@ public class GeckoThread extends Thread // and then fire us up Log.i(LOGTAG, "RunGecko - args = " + args); GeckoAppShell.runGecko(app.getApplication().getPackageResourcePath(), args, mUri, type); } + + public void handleMessage(String event, JSONObject message) { + if ("Gecko:Ready".equals(event)) { + GeckoAppShell.getEventDispatcher().unregisterEventListener(event, this); + setLaunchState(LaunchState.GeckoRunning); + GeckoAppShell.sendPendingEventsToGecko(); + } + } + + public static boolean checkLaunchState(LaunchState checkState) { + synchronized (sLaunchState) { + return sLaunchState == checkState; + } + } + + static void setLaunchState(LaunchState setState) { + synchronized (sLaunchState) { + sLaunchState = setState; + } + } + + /** + * Set the launch state to <code>setState</code> and return true if the current launch + * state is <code>checkState</code>; otherwise do nothing and return false. + */ + static boolean checkAndSetLaunchState(LaunchState checkState, LaunchState setState) { + synchronized (sLaunchState) { + if (sLaunchState != checkState) + return false; + sLaunchState = setState; + return true; + } + } }
--- a/mobile/android/base/MarketplaceApp.java.in +++ b/mobile/android/base/MarketplaceApp.java.in @@ -13,16 +13,17 @@ import android.os.SystemClock; import android.util.Log; import android.view.MenuItem; import org.json.JSONObject; import org.mozilla.gecko.GeckoApp; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoEvent; +import org.mozilla.gecko.GeckoThread; import org.mozilla.gecko.WebAppAllocator; /* * This is a stub activity, meant to just install the marketplace WebApp * and then launch it */ public class MarketplaceApp extends WebApp { private static final String LOGTAG = "GeckoMarketplaceApp"; @@ -51,17 +52,17 @@ public class MarketplaceApp extends WebA protected String getDefaultProfileName() { return "default"; } @Override protected void onNewIntent(Intent intent) { Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onNewIntent"); - if (checkLaunchState(LaunchState.GeckoExiting)) { + if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoExiting)) { // We're exiting and shouldn't try to do anything else just incase // we're hung for some reason we'll force the process to exit System.exit(0); return; } // if we were previously OOM killed, we can end up here when launching // from external shortcuts, so set this as the intent for initialization
--- a/mobile/android/base/MemoryMonitor.java +++ b/mobile/android/base/MemoryMonitor.java @@ -145,17 +145,17 @@ class MemoryMonitor extends BroadcastRec // if we're not going to a higher level we probably don't // need to run another round of the same memory reductions // we did on the last memory pressure increase. return; } // TODO hook in memory-reduction stuff for different levels here if (level >= MEMORY_PRESSURE_MEDIUM) { - if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) { + if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { GeckoAppShell.onLowMemory(); } GeckoAppShell.geckoEventSync(); Favicons.getInstance().clearMemCache(); } } private boolean decreaseMemoryPressure() { @@ -203,17 +203,17 @@ class MemoryMonitor extends BroadcastRec private final Context mContext; public StorageReducer(final Context context) { this.mContext = context; } @Override public void run() { // this might get run right on startup, if so wait 10 seconds and try again - if (!GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) { + if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { GeckoAppShell.getHandler().postDelayed(this, 10000); return; } if (!mStoragePressure) { // pressure is off, so we can abort return; }
--- a/mobile/android/base/db/GeckoProvider.java.in +++ b/mobile/android/base/db/GeckoProvider.java.in @@ -9,20 +9,20 @@ import java.io.File; import java.io.IOException; import java.lang.IllegalArgumentException; import java.util.HashMap; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Random; -import org.mozilla.gecko.GeckoApp; import org.mozilla.gecko.GeckoAppShell; +import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.GeckoProfile; -import org.mozilla.gecko.GeckoEvent; +import org.mozilla.gecko.GeckoThread; import org.mozilla.gecko.db.BrowserContract.CommonColumns; import org.mozilla.gecko.db.DBUtils; import org.mozilla.gecko.db.BrowserContract.Passwords; import org.mozilla.gecko.db.BrowserContract.DeletedPasswords; import org.mozilla.gecko.db.BrowserContract.SyncColumns; import org.mozilla.gecko.db.BrowserContract; import org.mozilla.gecko.sqlite.SQLiteBridge; import org.mozilla.gecko.sqlite.SQLiteBridgeException; @@ -127,17 +127,17 @@ public abstract class GeckoProvider exte // this will throw if the database can't be found // we should attempt to set it up if Gecko is running dbNeedsSetup = true; Log.e(mLogTag, "Error getting version ", ex); // if Gecko is not running, we should bail out. Otherwise we try to // let Gecko build the database for us - if (!GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) { + if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { Log.e(mLogTag, "Can not set up database. Gecko is not running"); return null; } } // If the database is not set up yet, or is the wrong schema version, we send an initialize // call to Gecko. Gecko will handle building the database file correctly, as well as any // migrations that are necessary
--- a/mobile/android/base/tests/BaseTest.java.in +++ b/mobile/android/base/tests/BaseTest.java.in @@ -50,23 +50,23 @@ abstract class BaseTest extends Activity private String mLogFile; protected String mProfile; private static ListView bookmarkList; protected void blockForGeckoReady() { try { Actions.EventExpecter geckoReadyExpector = mActions.expectGeckoEvent("Gecko:Ready"); ClassLoader classLoader = getActivity().getClassLoader(); - Class appsCls = classLoader.loadClass("org.mozilla.gecko.GeckoApp"); - Class launchStateCls = classLoader.loadClass("org.mozilla.gecko.GeckoApp$LaunchState"); + Class appsCls = classLoader.loadClass("org.mozilla.gecko.GeckoThread"); + Class launchStateCls = classLoader.loadClass("org.mozilla.gecko.GeckoThread$LaunchState"); Method checkLaunchState = appsCls.getMethod("checkLaunchState", launchStateCls); Object states[] = launchStateCls.getEnumConstants(); Boolean ret = (Boolean)checkLaunchState.invoke(null, states[3]); if (!ret.booleanValue()) { - geckoReadyExpector.blockForEvent(); + geckoReadyExpector.blockForEvent(); } } catch (Exception e) { mAsserter.dumpLog("Exception in blockForGeckoReady", e); } } static { try {