Bug 1330714 - Allow distributions to override firstrun wizard. r=rnewman a=gchang
authorMichael Kaply <mozilla@kaply.com>
Fri, 17 Feb 2017 11:33:03 -0600
changeset 376350 8d0c434a75426db2555c7e226a1fa38d93940622
parent 376349 94debbbf7e5a08a93acfac75f2d7436df6d10cbf
child 376351 27470afc80e8cbf7a2bb016acc03fc7451faec4d
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman, gchang
bugs1330714
milestone53.0a2
Bug 1330714 - Allow distributions to override firstrun wizard. r=rnewman a=gchang MozReview-Commit-ID: 8vEqApRi9bC
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunAnimationContainer.java
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -7,16 +7,17 @@ package org.mozilla.gecko;
 
 import android.Manifest;
 import android.annotation.TargetApi;
 import android.app.DownloadManager;
 import android.content.ContentProviderClient;
 import android.os.Environment;
 import android.os.Process;
 import android.support.annotation.NonNull;
+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;
 import org.mozilla.gecko.AppConstants.Versions;
@@ -921,16 +922,35 @@ public class BrowserApp extends GeckoApp
                                 .apply();
             }
         } finally {
             StrictMode.setThreadPolicy(savedPolicy);
         }
     }
 
     /**
+     * Code to actually show the first run pager, separated
+     * for distribution purposes.
+     */
+    @UiThread
+    private void checkFirstrunInternal() {
+        showFirstrunPager();
+
+        if (HardwareUtils.isTablet()) {
+            mTabStrip.setOnTabChangedListener(new TabStripInterface.OnTabAddedOrRemovedListener() {
+                @Override
+                public void onTabChanged() {
+                    hideFirstrunPager(TelemetryContract.Method.BUTTON);
+                    mTabStrip.setOnTabChangedListener(null);
+                }
+            });
+        }
+    }
+
+    /**
      * Check and show the firstrun pane if the browser has never been launched and
      * is not opening an external link from another application.
      *
      * @param context Context of application; used to show firstrun pane if appropriate
      * @param intent Intent that launched this activity
      */
     private void checkFirstrun(Context context, SafeIntent intent) {
         if (getProfile().inGuestMode()) {
@@ -943,26 +963,50 @@ public class BrowserApp extends GeckoApp
             // in the firstrun pane being shown.
             return;
         }
         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
 
         try {
             final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
 
-            if (prefs.getBoolean(FirstrunAnimationContainer.PREF_FIRSTRUN_ENABLED, true)) {
+            if (prefs.getBoolean(FirstrunAnimationContainer.PREF_FIRSTRUN_ENABLED_OLD, true) &&
+                prefs.getBoolean(FirstrunAnimationContainer.PREF_FIRSTRUN_ENABLED, true)) {
                 if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
-                    showFirstrunPager();
-
-                    if (HardwareUtils.isTablet()) {
-                        mTabStrip.setOnTabChangedListener(new TabStripInterface.OnTabAddedOrRemovedListener() {
+                    // Check to see if a distribution has turned off the first run pager.
+                    final Distribution distribution = Distribution.getInstance(BrowserApp.this);
+                    if (!distribution.shouldWaitForSystemDistribution()) {
+                        checkFirstrunInternal();
+                    } else {
+                        distribution.addOnDistributionReadyCallback(new Distribution.ReadyCallback() {
                             @Override
-                            public void onTabChanged() {
-                                hideFirstrunPager(TelemetryContract.Method.BUTTON);
-                                mTabStrip.setOnTabChangedListener(null);
+                            public void distributionNotFound() {
+                                ThreadUtils.postToUiThread(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        checkFirstrunInternal();
+                                    }
+                                });
+                            }
+
+                            @Override
+                            public void distributionFound(final Distribution distribution) {
+                                // Check preference again in case distribution turned it off.
+                                if (prefs.getBoolean(FirstrunAnimationContainer.PREF_FIRSTRUN_ENABLED, true)) {
+                                    ThreadUtils.postToUiThread(new Runnable() {
+                                        @Override
+                                        public void run() {
+                                            checkFirstrunInternal();
+                                        }
+                                    });
+                                }
+                            }
+
+                            @Override
+                            public void distributionArrivedLate(final Distribution distribution) {
                             }
                         });
                     }
                 }
 
                 // Don't bother trying again to show the v1 minimal first run.
                 prefs.edit().putBoolean(FirstrunAnimationContainer.PREF_FIRSTRUN_ENABLED, false).apply();
 
--- a/mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
+++ b/mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
@@ -221,16 +221,21 @@ public class Distribution {
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             public void run() {
                 boolean distributionSet = distribution.doInit();
                 if (distributionSet) {
                     String preferencesJSON = "";
                     try {
                         final File descFile = distribution.getDistributionFile("preferences.json");
+                        if (descFile == null) {
+                            // This can happen if we have a distribution directory, but no
+                            // preferences.json file.
+                            throw new IOException("preferences.json not found");
+                        }
                         preferencesJSON = FileUtils.readStringFromFile(descFile);
                     } catch (IOException e) {
                         Log.e(LOGTAG, "Error getting distribution descriptor file.", e);
                     }
                     GeckoAppShell.notifyObservers("Distribution:Set", preferencesJSON);
                 }
             }
         });
@@ -686,16 +691,38 @@ public class Distribution {
     /**
      * @return true if we found a system distribution. Sets distributionDir in that case.
      */
     private boolean checkSystemDistribution() {
         return checkDirectories(getSystemDistributionDirectories(context));
     }
 
     /**
+     * @return true if we should wait for a system distribution to load.
+     * Not applicable to APK or OTA distributions.
+     */
+    public boolean shouldWaitForSystemDistribution() {
+        if (state == STATE_NONE) {
+            return false;
+        }
+        if (state == STATE_SET) {
+            return true;
+        }
+
+        final String[] directories = getSystemDistributionDirectories(context);
+        for (String path : directories) {
+            final File directory = new File(path);
+            if (directory.exists()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * @return true if one of the specified distribution directories exists.  Sets distributionDir in that case.
      */
     private boolean checkDirectories(String[] directories) {
         for (String path : directories) {
             File directory = new File(path);
             if (directory.exists()) {
                 distributionDir = directory;
                 return true;
--- a/mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunAnimationContainer.java
+++ b/mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunAnimationContainer.java
@@ -13,23 +13,26 @@ import android.view.View;
 import android.widget.LinearLayout;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.Experiments;
+import org.mozilla.gecko.preferences.GeckoPreferences;
 
 /**
  * A container for the pager and the entire first run experience.
  * This is used for animation purposes.
  */
 public class FirstrunAnimationContainer extends LinearLayout {
-    public static final String PREF_FIRSTRUN_ENABLED = "startpane_enabled";
+    // See bug 1330714. Need NON_PREF_PREFIX to set from distribution.
+    public static final String PREF_FIRSTRUN_ENABLED_OLD = "startpane_enabled";
+    public static final String PREF_FIRSTRUN_ENABLED = GeckoPreferences.NON_PREF_PREFIX + "startpane_enabled";
 
     public static interface OnFinishListener {
         public void onFinish();
     }
 
     private FirstrunPager pager;
     private boolean visible;
     private OnFinishListener onFinishListener;