bug 704217 - Quit doesn't work before Gecko is up r=dougt
authorBrad Lassey <blassey@mozilla.com>
Thu, 24 Nov 2011 02:04:26 -0500
changeset 83598 498a331fe654fd9c5b31f8aec76ebc5981f2adb4
parent 83597 98861dbb32772fbd351ccd2cc68b90fe117f5567
child 83599 f8505fcb5808f61826911a643f6717bfa4552883
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougt
bugs704217
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 704217 - Quit doesn't work before Gecko is up r=dougt
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/chrome/content/browser.js
widget/src/android/AndroidBridge.cpp
widget/src/android/AndroidBridge.h
widget/src/android/nsAppShell.cpp
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -459,17 +459,24 @@ abstract public class GeckoApp
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         Tab tab = null;
         Intent intent = null;
         switch (item.getItemId()) {
             case R.id.quit:
-                GeckoAppShell.sendEventToGecko(new GeckoEvent("Browser:Quit", null));
+                synchronized(sLaunchState) {
+                    if (sLaunchState == LaunchState.GeckoRunning)
+                        GeckoAppShell.notifyGeckoOfEvent(
+                            new GeckoEvent("Browser:Quit", null));
+                    else
+                        System.exit(0);
+                    sLaunchState = LaunchState.GeckoExiting;
+                }
                 return true;
             case R.id.bookmark:
                 tab = Tabs.getInstance().getSelectedTab();
                 if (tab != null) {
                     if (item.isChecked()) {
                         tab.removeBookmark();
                         Toast.makeText(this, R.string.bookmark_removed, Toast.LENGTH_SHORT).show();
                         item.setIcon(R.drawable.ic_menu_bookmark_add);
@@ -806,16 +813,18 @@ abstract public class GeckoApp
                 GeckoPreferences.setData(jsonPrefs);
                 mMainHandler.post(new Runnable() {
                     public void run() {
                         if (sMenu != null)
                             sMenu.findItem(R.id.preferences).setEnabled(true);
                     }
                 });
             } else if (event.equals("Gecko:Ready")) {
+                setLaunchState(GeckoApp.LaunchState.GeckoRunning);
+                GeckoAppShell.sendPendingEventsToGecko();
                 // retrieve the list of preferences from our preferences.xml file
                 XmlResourceParser parser = getResources().getXml(R.xml.preferences);
                 ArrayList<String> prefs = new ArrayList<String>();
                 while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                     if (parser.getEventType() == XmlPullParser.START_TAG) {
                         String attr = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "key");
                         if (attr != null) {
                             prefs.add(attr);
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -474,17 +474,18 @@ public class GeckoAppShell
                 /* Restore the view coordinates in case the caller further processes this event */
                 event.setLocation(origX, origY);
                 return true;
             }
         });
 
         layerController.notifyLayerClientOfGeometryChange();
     }
-    private static void sendPendingEventsToGecko() {
+
+    static void sendPendingEventsToGecko() {
         try {
             while (!gPendingEvents.isEmpty()) {
                 GeckoEvent e = gPendingEvents.removeFirst();
                 notifyGeckoOfEvent(e);
             }
         } catch (NoSuchElementException e) {}
     }
 
@@ -607,23 +608,16 @@ public class GeckoAppShell
     public static void moveTaskToBack() {
         GeckoApp.mAppContext.moveTaskToBack(true);
     }
 
     public static void returnIMEQueryResult(String result, int selectionStart, int selectionLength) {
         mInputConnection.returnIMEQueryResult(result, selectionStart, selectionLength);
     }
 
-    static void onAppShellReady()
-    {
-        // mLaunchState can only be Launched at this point
-        GeckoApp.mAppContext.setLaunchState(GeckoApp.LaunchState.GeckoRunning);
-        sendPendingEventsToGecko();
-    }
-
     static void onXreExit() {
         // mLaunchState can only be Launched or GeckoRunning at this point
         GeckoApp.mAppContext.setLaunchState(GeckoApp.LaunchState.GeckoExiting);
         Log.i(LOGTAG, "XRE exited");
         if (gRestartScheduled) {
             GeckoApp.mAppContext.doRestart();
         } else {
             Log.i(LOGTAG, "we're done, good bye");
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -347,16 +347,17 @@ var BrowserApp = {
         }
       };
 
       sendMessageToJava(message);
     }
   },
 
   quit: function quit() {
+      Cu.reportError("got quit quit message");
       window.QueryInterface(Ci.nsIDOMChromeWindow).minimize();
       window.close();
   },
 
   saveAsPDF: function saveAsPDF(aBrowser) {
     // Create the final destination file location
     let ContentAreaUtils = {};
     Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", ContentAreaUtils);
--- a/widget/src/android/AndroidBridge.cpp
+++ b/widget/src/android/AndroidBridge.cpp
@@ -120,17 +120,16 @@ AndroidBridge::Init(JNIEnv *jEnv,
     jNotifyIMEEnabled = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEEnabled", "(ILjava/lang/String;Ljava/lang/String;Z)V");
     jNotifyIMEChange = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEChange", "(Ljava/lang/String;III)V");
     jAcknowledgeEventSync = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "acknowledgeEventSync", "()V");
 
     jEnableDeviceMotion = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableDeviceMotion", "(Z)V");
     jEnableLocation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableLocation", "(Z)V");
     jReturnIMEQueryResult = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "returnIMEQueryResult", "(Ljava/lang/String;II)V");
     jScheduleRestart = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scheduleRestart", "()V");
-    jNotifyAppShellReady = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onAppShellReady", "()V");
     jNotifyXreExit = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onXreExit", "()V");
     jGetHandlersForMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
     jGetHandlersForURL = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForURL", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
     jOpenUriExternal = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
     jGetMimeTypeFromExtensions = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
     jGetExtensionFromMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getExtensionFromMimeType", "(Ljava/lang/String;)Ljava/lang/String;");
     jMoveTaskToBack = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "moveTaskToBack", "()V");
     jGetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getClipboardText", "()Ljava/lang/String;");
@@ -358,25 +357,16 @@ AndroidBridge::ReturnIMEQueryResult(cons
     args[0].l = mJNIEnv->NewString(aResult, aLen);
     args[1].i = aSelStart;
     args[2].i = aSelLen;
     mJNIEnv->CallStaticVoidMethodA(mGeckoAppShellClass,
                                    jReturnIMEQueryResult, args);
 }
 
 void
-AndroidBridge::NotifyAppShellReady()
-{
-    ALOG_BRIDGE("AndroidBridge::NotifyAppShellReady");
-    mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyAppShellReady);
-
-    mURIFixup = do_GetService(NS_URIFIXUP_CONTRACTID);
-}
-
-void
 AndroidBridge::ScheduleRestart()
 {
     ALOG_BRIDGE("scheduling reboot");
     mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jScheduleRestart);
 }
 
 void
 AndroidBridge::NotifyXreExit()
@@ -585,18 +575,20 @@ AndroidBridge::ClipboardHasText()
     return true;
 }
 
 bool
 AndroidBridge::CanCreateFixupURI(const nsACString& aURIText)
 {
     ALOG_BRIDGE("AndroidBridge::CanCreateFixupURI");
 
-    if (!mURIFixup)
-        return false;
+    if (!mURIFixup) {
+        mURIFixup = do_GetService(NS_URIFIXUP_CONTRACTID);
+        if (!mURIFixup) return false;
+    }
 
     nsCOMPtr<nsIURI> targetURI;
 
     mURIFixup->CreateFixupURI(aURIText,
                               nsIURIFixup::FIXUP_FLAG_NONE,
                               getter_AddRefs(targetURI));
 
     return (targetURI != nsnull);
--- a/widget/src/android/AndroidBridge.h
+++ b/widget/src/android/AndroidBridge.h
@@ -140,18 +140,16 @@ public:
     void AcknowledgeEventSync();
 
     void EnableDeviceMotion(bool aEnable);
 
     void EnableLocation(bool aEnable);
 
     void ReturnIMEQueryResult(const PRUnichar *aResult, PRUint32 aLen, int aSelStart, int aSelLen);
 
-    void NotifyAppShellReady();
-
     void NotifyXreExit();
 
     void ScheduleRestart();
 
     void SetSoftwareLayerClient(jobject jobj);
     AndroidGeckoSoftwareLayerClient &GetSoftwareLayerClient() { return mSoftwareLayerClient; }
 
     void SetSurfaceView(jobject jobj);
--- a/widget/src/android/nsAppShell.cpp
+++ b/widget/src/android/nsAppShell.cpp
@@ -116,18 +116,16 @@ nsAppShell::Init()
     if (!gWidgetLog)
         gWidgetLog = PR_NewLogModule("Widget");
 #endif
 
     mObserversHash.Init();
 
     nsresult rv = nsBaseAppShell::Init();
     AndroidBridge* bridge = AndroidBridge::Bridge();
-    if (bridge)
-        bridge->NotifyAppShellReady();
 
     nsCOMPtr<nsIObserverService> obsServ =
         mozilla::services::GetObserverService();
     if (obsServ) {
         obsServ->AddObserver(this, "xpcom-shutdown", false);
     }
 
     if (!bridge)