Bug 1059792 - Launching Firefox for the first time through an external intent should not display First Run experience. r=margaret
☠☠ backed out by 2119d0833157 ☠ ☠
authorChenxia Liu <liuche@mozilla.com>
Thu, 18 Sep 2014 17:49:08 -0700
changeset 206151 297008b7e1f6e0d3d340bb568d3d26cca99c02d5
parent 206150 8351557bf4ffc0bf59dd532b626bf636460c46ff
child 206152 2119d0833157fbc31c5d2a0866191e89857ce348
push id27514
push usercbook@mozilla.com
push dateFri, 19 Sep 2014 12:24:09 +0000
treeherdermozilla-central@3475e6a1665a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret
bugs1059792
milestone35.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 1059792 - Launching Firefox for the first time through an external intent should not display First Run experience. r=margaret
mobile/android/base/BrowserApp.java
mobile/android/base/GeckoProfile.java
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -77,17 +77,16 @@ import org.mozilla.gecko.widget.GeckoAct
 
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.BroadcastReceiver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
@@ -148,17 +147,17 @@ public class BrowserApp extends GeckoApp
     public static final String GUEST_BROWSING_ARG = "--guest";
 
     private static final String STATE_ABOUT_HOME_TOP_PADDING = "abouthome_top_padding";
 
     private static final String BROWSER_SEARCH_TAG = "browser_search";
 
     // Request ID for startActivityForResult.
     private static final int ACTIVITY_REQUEST_PREFERENCES = 1001;
-    public static final String ACTION_NEW_PROFILE = "org.mozilla.gecko.NEW_PROFILE";
+    private static final String PREF_FIRSTRUN_STARTPANE = "firstrun_startpane";
 
     private BrowserSearch mBrowserSearch;
     private View mBrowserSearchContainer;
 
     public ViewGroup mBrowserChrome;
     public ViewFlipper mActionBarFlipper;
     public ActionModeCompatView mActionBar;
     private BrowserToolbar mBrowserToolbar;
@@ -606,18 +605,16 @@ public class BrowserApp extends GeckoApp
             "Reader:ListStatusRequest",
             "Reader:Removed",
             "Reader:Share",
             "Settings:Show",
             "Telemetry:Gather",
             "Updater:Launch",
             "BrowserToolbar:Visibility");
 
-        registerOnboardingReceiver(this);
-
         Distribution distribution = Distribution.init(this);
 
         // Init suggested sites engine in BrowserDB.
         final SuggestedSites suggestedSites = new SuggestedSites(appContext, distribution);
         BrowserDB.setSuggestedSites(suggestedSites);
 
         JavaAddonManager.getInstance().init(appContext);
         mSharedPreferencesHelper = new SharedPreferencesHelper(appContext);
@@ -668,34 +665,44 @@ public class BrowserApp extends GeckoApp
         if (getProfile().inGuestMode()) {
             GuestSession.showNotification(this);
         } else {
             // If we're restarting, we won't destroy the activity. Make sure we remove any guest notifications that might have been shown.
             GuestSession.hideNotification(this);
         }
     }
 
-    private void registerOnboardingReceiver(Context context) {
-        final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
-
-        // Receiver for launching first run start pane on new profile creation.
-        mOnboardingReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                launchStartPane(BrowserApp.this);
+    /**
+     * Check and show Onboarding start pane if Firefox has never been launched and
+     * is not opening a external link from another application.
+     *
+     * @param context Context of application; used to show Start Pane if appropriate
+     * @param intentAction Intent that launched this activity
+     */
+    private void checkStartPane(Context context, String intentAction) {
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
+        try {
+            final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
+
+            if (prefs.contains(PREF_FIRSTRUN_STARTPANE)) {
+                return;
+             }
+
+            if (!Intent.ACTION_VIEW.equals(intentAction)) {
+                final Intent startIntent = new Intent(this, StartPane.class);
+                context.startActivity(startIntent);
             }
-        };
-
-        lbm.registerReceiver(mOnboardingReceiver, new IntentFilter(ACTION_NEW_PROFILE));
-    }
-
-    private void launchStartPane(Context context) {
-         final Intent startIntent = new Intent(context, StartPane.class);
-         context.startActivity(startIntent);
-     }
+            // Don't bother trying again to show the v1 minimal first run.
+            prefs.edit().putBoolean(PREF_FIRSTRUN_STARTPANE, true).apply();
+
+        } finally {
+            StrictMode.setThreadPolicy(savedPolicy);
+        }
+      }
 
     private Class<?> getMediaPlayerManager() {
         if (AppConstants.MOZ_MEDIA_PLAYER) {
             try {
                 return Class.forName("org.mozilla.gecko.MediaPlayerManager");
             } catch(Exception ex) {
                 // Ignore failures
                 Log.e(LOGTAG, "No native casting support", ex);
@@ -1087,16 +1094,18 @@ public class BrowserApp extends GeckoApp
             }
         }
 
         super.onDestroy();
     }
 
     @Override
     protected void initializeChrome() {
+        checkStartPane(this, getIntent().getAction());
+
         super.initializeChrome();
 
         mDoorHangerPopup.setAnchor(mBrowserToolbar.getDoorHangerAnchor());
 
         mDynamicToolbar.setLayerView(mLayerView);
         setDynamicToolbarEnabled(mDynamicToolbar.isEnabled());
 
         // Intercept key events for gamepad shortcuts
@@ -2563,17 +2572,16 @@ public class BrowserApp extends GeckoApp
         MenuItem desktopMode = aMenu.findItem(R.id.desktop_mode);
         MenuItem enterGuestMode = aMenu.findItem(R.id.new_guest_session);
         MenuItem exitGuestMode = aMenu.findItem(R.id.exit_guest_session);
 
         // Only show the "Quit" menu item on pre-ICS, television devices,
         // or if the user has explicitly enabled the clear on shutdown pref.
         // (We check the pref last to save the pref read.)
         // In ICS+, it's easy to kill an app through the task switcher.
-        final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
         final boolean visible = Versions.preICS ||
                                 HardwareUtils.isTelevision() ||
                                 !PrefUtils.getStringSet(GeckoSharedPrefs.forProfile(this),
                                                         ClearOnShutdownPref.PREF,
                                                         new HashSet<String>()).isEmpty();
         aMenu.findItem(R.id.quit).setVisible(visible);
 
         if (tab == null || tab.getURL() == null) {
@@ -2927,16 +2935,18 @@ public class BrowserApp extends GeckoApp
 
         super.onNewIntent(intent);
 
         if (AppConstants.MOZ_ANDROID_BEAM && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
             String uri = intent.getDataString();
             GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(uri));
         }
 
+        checkStartPane(this, action);
+
         if (!mInitialized) {
             return;
         }
 
         // Only solicit feedback when the app has been launched from the icon shortcut.
         if (!Intent.ACTION_MAIN.equals(action)) {
             return;
         } else if (GuestSession.NOTIFICATION_INTENT.equals(action)) {
--- a/mobile/android/base/GeckoProfile.java
+++ b/mobile/android/base/GeckoProfile.java
@@ -20,18 +20,16 @@ import org.mozilla.gecko.GeckoProfileDir
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.distribution.Distribution;
 import org.mozilla.gecko.mozglue.RobocopTarget;
 import org.mozilla.gecko.util.INIParser;
 import org.mozilla.gecko.util.INISection;
 
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
-import android.support.v4.content.LocalBroadcastManager;
 import android.text.TextUtils;
 import android.util.Log;
 
 public final class GeckoProfile {
     private static final String LOGTAG = "GeckoProfile";
 
     // Used to "lock" the guest profile, so that we'll always restart in it
     private static final String LOCK_FILE_NAME = ".active_lock";
@@ -651,20 +649,16 @@ public final class GeckoProfile {
             } finally {
                 writer.close();
             }
         } catch (Exception e) {
             // Best-effort.
             Log.w(LOGTAG, "Couldn't write times.json.", e);
         }
 
-        LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(mApplicationContext);
-        final Intent intent = new Intent(BrowserApp.ACTION_NEW_PROFILE);
-        lbm.sendBroadcast(intent);
-
         return profileDir;
     }
 
     /**
      * This method is called once, immediately before creation of the profile
      * directory completes.
      *
      * It queues up work to be done in the background to prepare the profile,