Bug 1337115 - Part 1 - Make "Is first run" pref generally useable. r=sebastian
authorJan Henning <jh+bugzilla@buttercookie.de>
Thu, 23 Feb 2017 22:16:26 +0100
changeset 394419 1f45e38b27af6a061a9b71dcdff3cf9074d4b629
parent 394418 d3241c1454e4c6639533ecc3c38c7f7912f7f0b3
child 394420 b25d9cfea3f9b5b822109af7ea4d90ae04463a7e
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian
bugs1337115
milestone54.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 1337115 - Part 1 - Make "Is first run" pref generally useable. r=sebastian This pref could be useful for things outside of the TelemetryCorePingDelegate as well, so we have it live in GeckoApp now. MozReview-Commit-ID: 2JZ3vNqSzcl
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryCorePingDelegate.java
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -1210,16 +1210,18 @@ public class BrowserApp extends GeckoApp
         }
 
         // We only show the guest mode notification when our activity is in the foreground.
         GuestSession.hideNotification(this);
 
         for (final BrowserAppDelegate delegate : delegates) {
             delegate.onStop(this);
         }
+
+        onAfterStop();
     }
 
     @Override
     public void onWindowFocusChanged(boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
 
         // Sending a message to the toolbar when the browser window gains focus
         // This is needed for qr code input
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -158,16 +158,20 @@ public abstract class GeckoApp
     public static final String LAST_SELECTED_TAB           = "lastSelectedTab";
 
     public static final String PREFS_ALLOW_STATE_BUNDLE    = "allowStateBundle";
     public static final String PREFS_VERSION_CODE          = "versionCode";
     public static final String PREFS_WAS_STOPPED           = "wasStopped";
     public static final String PREFS_CRASHED_COUNT         = "crashedCount";
     public static final String PREFS_CLEANUP_TEMP_FILES    = "cleanupTempFiles";
 
+    // Originally, this was only used for the telemetry core ping logic. To avoid
+    // having to write custom migration logic, we just keep the original pref key.
+    public static final String PREFS_IS_FIRST_RUN = "telemetry-isFirstRun";
+
     public static final String SAVED_STATE_IN_BACKGROUND   = "inBackground";
     public static final String SAVED_STATE_PRIVATE_SESSION = "privateSession";
 
     // Delay before running one-time "cleanup" tasks that may be needed
     // after a version upgrade.
     private static final int CLEANUP_DEFERRAL_SECONDS = 15;
 
     private static boolean sAlreadyLoaded;
@@ -370,16 +374,20 @@ public abstract class GeckoApp
         return this;
     }
 
     @Override
     public SharedPreferences getSharedPreferences() {
         return GeckoSharedPrefs.forApp(this);
     }
 
+    public SharedPreferences getSharedPreferencesForProfile() {
+        return GeckoSharedPrefs.forProfile(this);
+    }
+
     @Override
     public Activity getActivity() {
         return this;
     }
 
     @Override
     public void addAppStateListener(GeckoAppShell.AppStateListener listener) {
         mAppStateListeners.add(listener);
@@ -558,17 +566,17 @@ public abstract class GeckoApp
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         if (item.getItemId() == R.id.quit) {
             // Make sure the Guest Browsing notification goes away when we quit.
             GuestSession.hideNotification(this);
 
-            final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
+            final SharedPreferences prefs = getSharedPreferencesForProfile();
             final Set<String> clearSet =
                     PrefUtils.getStringSet(prefs, ClearOnShutdownPref.PREF, new HashSet<String>());
 
             final JSONObject clearObj = new JSONObject();
             for (String clear : clearSet) {
                 try {
                     clearObj.put(clear, true);
                 } catch (JSONException ex) {
@@ -1453,17 +1461,17 @@ public abstract class GeckoApp
                     @Override
                     public void run() {
                         GeckoApp.this.onLocaleReady(uiLocale);
                     }
                 });
 
                 // We use per-profile prefs here, because we're tracking against
                 // a Gecko pref. The same applies to the locale switcher!
-                BrowserLocaleManager.storeAndNotifyOSLocale(GeckoSharedPrefs.forProfile(GeckoApp.this), osLocale);
+                BrowserLocaleManager.storeAndNotifyOSLocale(getSharedPreferencesForProfile(), osLocale);
             }
         });
 
         IntentHelper.init(this);
     }
 
     @Override
     public void onStart() {
@@ -1480,16 +1488,28 @@ public abstract class GeckoApp
         super.onStop();
         // Overriding here is not necessary, but we do this so we don't
         // forget to add the abort if we override this method later.
         if (mIsAbortingAppLaunch) {
             return;
         }
     }
 
+
+    /**
+     * Derived classes may call this if they require something to be done *after* they've
+     * done their onStop() handling.
+     */
+    protected void onAfterStop() {
+        final SharedPreferences sharedPrefs = getSharedPreferencesForProfile();
+        if (sharedPrefs.getBoolean(PREFS_IS_FIRST_RUN, true)) {
+            sharedPrefs.edit().putBoolean(PREFS_IS_FIRST_RUN, false).apply();
+        }
+    }
+
     /**
      * At this point, the resource system and the rest of the browser are
      * aware of the locale.
      *
      * Now we can display strings!
      *
      * You can think of this as being something like a second phase of onCreate,
      * where you can do string-related operations. Use this in place of embedding
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryCorePingDelegate.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryCorePingDelegate.java
@@ -7,16 +7,17 @@
 package org.mozilla.gecko.telemetry;
 
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.support.annotation.Nullable;
 import android.support.annotation.WorkerThread;
 import android.util.Log;
 import org.mozilla.gecko.BrowserApp;
+import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.GeckoSharedPrefs;
 import org.mozilla.gecko.adjust.AttributionHelperListener;
 import org.mozilla.gecko.telemetry.measurements.CampaignIdMeasurements;
 import org.mozilla.gecko.delegates.BrowserAppDelegateWithReference;
 import org.mozilla.gecko.distribution.DistributionStoreCallback;
 import org.mozilla.gecko.search.SearchEngineManager;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
@@ -31,18 +32,16 @@ import java.io.IOException;
 /**
  * An activity-lifecycle delegate for uploading the core ping.
  */
 public class TelemetryCorePingDelegate extends BrowserAppDelegateWithReference
         implements SearchEngineManager.SearchEngineCallback, AttributionHelperListener {
     private static final String LOGTAG = StringUtils.safeSubstring(
             "Gecko" + TelemetryCorePingDelegate.class.getSimpleName(), 0, 23);
 
-    private static final String PREF_IS_FIRST_RUN = "telemetry-isFirstRun";
-
     private TelemetryDispatcher telemetryDispatcher; // lazy
     private final SessionMeasurements sessionMeasurements = new SessionMeasurements();
 
     @Override
     public void onStart(final BrowserApp browserApp) {
         TelemetryPreferences.initPreferenceObserver(browserApp, browserApp.getProfile().getName());
 
         // We don't upload in onCreate because that's only called when the Activity needs to be instantiated
@@ -65,20 +64,18 @@ public class TelemetryCorePingDelegate e
         // Caveats:
         //   * onStop is not guaranteed to be called in low memory conditions so it's possible we won't upload,
         // but it's better than it was before.
         //   * Besides first run (because of this call), we can never get the user's *last* session data.
         //
         // If we are really interested in the user's last session data, we could consider uploading in onStop
         // but it's less robust (see discussion in bug 1277091).
         final SharedPreferences sharedPrefs = getSharedPreferences(browserApp);
-        if (sharedPrefs.getBoolean(PREF_IS_FIRST_RUN, true)) {
-            sharedPrefs.edit()
-                    .putBoolean(PREF_IS_FIRST_RUN, false)
-                    .apply();
+        if (sharedPrefs.getBoolean(GeckoApp.PREFS_IS_FIRST_RUN, true)) {
+            // GeckoApp will set this pref to false afterwards.
             uploadPing(browserApp);
         }
     }
 
     private void uploadPing(final BrowserApp browserApp) {
         final SearchEngineManager searchEngineManager = browserApp.getSearchEngineManager();
         searchEngineManager.getEngine(this);
     }