Bug 1077590 - Part 4: fix profile access in BrowserApp. r=mfinkle
authorRichard Newman <rnewman@mozilla.com>
Mon, 12 Jan 2015 20:58:01 -0800
changeset 223534 fbdcb7d48dd9b11877048e542b6abd854af97541
parent 223533 0211ab7ba0d828fa1017011abce8f6d627b1992a
child 223535 c9ff49636eefb8aaedca8de13b0ff684389d2c13
push id28096
push usercbook@mozilla.com
push dateTue, 13 Jan 2015 13:27:54 +0000
treeherdermozilla-central@0500f1032ea1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs1077590
milestone38.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 1077590 - Part 4: fix profile access in BrowserApp. r=mfinkle
mobile/android/base/BrowserApp.java
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoProfile.java
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -492,17 +492,23 @@ public class BrowserApp extends GeckoApp
         return super.onKeyUp(keyCode, event);
     }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         mAboutHomeStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_ABOUTHOME");
 
         final Intent intent = getIntent();
+
+        // Note that we're calling GeckoProfile.get *before GeckoApp.onCreate*.
+        // This means we're reliant on the logic in GeckoProfile to correctly
+        // look up our launch intent (via BrowserApp's Activity-ness) and pull
+        // out the arguments. Be careful if you change that!
         final GeckoProfile p = GeckoProfile.get(this);
+
         if (p != null && !p.inGuestMode()) {
             // This is *only* valid because we never want to use the guest mode
             // profile concurrently with a normal profile -- no syncing to it,
             // no dual-profile usage, nothing. BrowserApp startup with a conventional
             // GeckoProfile will cause the guest profile to be deleted.
             GeckoProfile.maybeCleanupGuestProfile(this);
         }
 
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1157,43 +1157,25 @@ public abstract class GeckoApp
 
         earlyStartJavaSampler(intent);
 
         // GeckoLoader wants to dig some environment variables out of the
         // incoming intent, so pass it in here. GeckoLoader will do its
         // business later and dispose of the reference.
         GeckoLoader.setLastIntent(intent);
 
-        if (mProfile == null) {
-            String profileName = null;
-            String profilePath = null;
-            if (args != null) {
-                if (args.contains("-P")) {
-                    Pattern p = Pattern.compile("(?:-P\\s*)(\\w*)(\\s*)");
-                    Matcher m = p.matcher(args);
-                    if (m.find()) {
-                        profileName = m.group(1);
-                    }
-                }
-
-                if (args.contains("-profile")) {
-                    Pattern p = Pattern.compile("(?:-profile\\s*)(\\S*)(\\s*)");
-                    Matcher m = p.matcher(args);
-                    if (m.find()) {
-                        profilePath =  m.group(1);
-                    }
-                    if (profileName == null) {
-                        profileName = GeckoProfile.DEFAULT_PROFILE;
-                    }
-                    GeckoProfile.sIsUsingCustomProfile = true;
-                }
-
-                if (profileName != null || profilePath != null) {
-                    mProfile = GeckoProfile.get(this, profileName, profilePath);
-                }
+        // If we don't already have a profile, but we do have arguments,
+        // let's see if they're enough to find one.
+        // Note that subclasses must ensure that if they try to access
+        // the profile prior to this code being run, then they do something
+        // similar.
+        if (mProfile == null && args != null) {
+            final GeckoProfile p = GeckoProfile.getFromArgs(this, args);
+            if (p != null) {
+                mProfile = p;
             }
         }
 
         // Speculatively pre-fetch the profile in the background.
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             public void run() {
                 getProfile();
--- a/mobile/android/base/GeckoProfile.java
+++ b/mobile/android/base/GeckoProfile.java
@@ -9,16 +9,18 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.nio.charset.Charset;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
 import org.mozilla.gecko.GeckoProfileDirectories.NoSuchProfileException;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.db.LocalBrowserDB;
 import org.mozilla.gecko.db.StubBrowserDB;
 import org.mozilla.gecko.distribution.Distribution;
 import org.mozilla.gecko.mozglue.RobocopTarget;
@@ -84,16 +86,56 @@ public final class GeckoProfile {
 
     // Constants to cache whether or not a profile is "locked".
     private enum LockState {
         LOCKED,
         UNLOCKED,
         UNDEFINED
     };
 
+    /**
+     * Warning: has a side-effect of setting sIsUsingCustomProfile.
+     * Can return null.
+     */
+    public static GeckoProfile getFromArgs(final Context context, final String args) {
+        if (args == null) {
+            return null;
+        }
+
+        String profileName = null;
+        String profilePath = null;
+        if (args.contains("-P")) {
+            final Pattern p = Pattern.compile("(?:-P\\s*)(\\w*)(\\s*)");
+            final Matcher m = p.matcher(args);
+            if (m.find()) {
+                profileName = m.group(1);
+            }
+        }
+
+        if (args.contains("-profile")) {
+            final Pattern p = Pattern.compile("(?:-profile\\s*)(\\S*)(\\s*)");
+            final Matcher m = p.matcher(args);
+            if (m.find()) {
+                profilePath =  m.group(1);
+            }
+
+            if (profileName == null) {
+                profileName = GeckoProfile.DEFAULT_PROFILE;
+            }
+
+            GeckoProfile.sIsUsingCustomProfile = true;
+        }
+
+        if (profileName == null && profilePath == null) {
+            return null;
+        }
+
+        return GeckoProfile.get(context, profileName, profilePath);
+    }
+
     public static GeckoProfile get(Context context) {
         boolean isGeckoApp = false;
         try {
             isGeckoApp = context instanceof GeckoApp;
         } catch (NoClassDefFoundError ex) {}
 
         if (isGeckoApp) {
             // Check for a cached profile on this context already
@@ -107,23 +149,31 @@ public final class GeckoProfile {
         final String args;
         if (context instanceof Activity) {
             args = ((Activity) context).getIntent().getStringExtra("args");
         } else {
             args = null;
         }
 
         if (GuestSession.shouldUse(context, args)) {
-            GeckoProfile p = GeckoProfile.getOrCreateGuestProfile(context);
+            final GeckoProfile p = GeckoProfile.getOrCreateGuestProfile(context);
             if (isGeckoApp) {
                 ((GeckoApp) context).mProfile = p;
             }
             return p;
         }
 
+        final GeckoProfile fromArgs = GeckoProfile.getFromArgs(context, args);
+        if (fromArgs != null) {
+            if (isGeckoApp) {
+                ((GeckoApp) context).mProfile = fromArgs;
+            }
+            return fromArgs;
+        }
+
         if (isGeckoApp) {
             final GeckoApp geckoApp = (GeckoApp) context;
             String defaultProfileName;
             try {
                 defaultProfileName = geckoApp.getDefaultProfileName();
             } catch (NoMozillaDirectoryException e) {
                 // If this failed, we're screwed. But there are so many callers that
                 // we'll just throw a RuntimeException.