Bug 1031872 - Don't use transitions for GeckoPreferences on Kindle Fire. r=lucasr
authorRichard Newman <rnewman@mozilla.com>
Mon, 14 Jul 2014 14:26:54 -0700
changeset 216002 a9dd41dffb2b55a4e0ccbd52a11d301c64587bef
parent 215811 2bb155ee786b42bcdee7b4266dc9d32dc8bfc971
child 216003 0bc4b2de1f951502d0087f28f82e9eed886d6e08
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslucasr
bugs1031872
milestone33.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 1031872 - Don't use transitions for GeckoPreferences on Kindle Fire. r=lucasr The Kindle always uses a black background for transitions. On all-white screens like our Settings panes, this looks awful. This patch skips transitions on those devices.
mobile/android/base/BrowserApp.java
mobile/android/base/preferences/GeckoPreferences.java
mobile/android/base/preferences/SyncPreference.java
mobile/android/base/util/HardwareUtils.java
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -1305,16 +1305,22 @@ public class BrowserApp extends GeckoApp
 
         } else if ("Settings:Show".equals(event)) {
             final String resource =
                     message.optString(GeckoPreferences.INTENT_EXTRA_RESOURCES, null);
             final Intent settingsIntent = new Intent(this, GeckoPreferences.class);
             GeckoPreferences.setResourceToOpen(settingsIntent, resource);
             startActivityForResult(settingsIntent, ACTIVITY_REQUEST_PREFERENCES);
 
+            // Don't use a transition to settings if we're on a device where that
+            // would look bad.
+            if (HardwareUtils.IS_KINDLE_DEVICE) {
+                overridePendingTransition(0, 0);
+            }
+
         } else if ("Telemetry:Gather".equals(event)) {
             Telemetry.HistogramAdd("PLACES_PAGES_COUNT",
                     BrowserDB.getCount(getContentResolver(), "history"));
             Telemetry.HistogramAdd("PLACES_BOOKMARKS_COUNT",
                     BrowserDB.getCount(getContentResolver(), "bookmarks"));
             Telemetry.HistogramAdd("FENNEC_FAVICONS_COUNT",
                     BrowserDB.getCount(getContentResolver(), "favicons"));
             Telemetry.HistogramAdd("FENNEC_THUMBNAILS_COUNT",
--- a/mobile/android/base/preferences/GeckoPreferences.java
+++ b/mobile/android/base/preferences/GeckoPreferences.java
@@ -28,16 +28,17 @@ import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.TelemetryContract.Method;
 import org.mozilla.gecko.background.announcements.AnnouncementsConstants;
 import org.mozilla.gecko.background.common.GlobalConstants;
 import org.mozilla.gecko.background.healthreport.HealthReportConstants;
 import org.mozilla.gecko.db.BrowserContract.SuggestedSites;
 import org.mozilla.gecko.home.HomePanelPicker;
 import org.mozilla.gecko.util.GeckoEventListener;
+import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.widget.FloatingHintEditText;
 
 import android.app.ActionBar;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.Fragment;
@@ -81,16 +82,21 @@ extends PreferenceActivity
 implements
 GeckoActivityStatus,
 GeckoEventListener,
 OnPreferenceChangeListener,
 OnSharedPreferenceChangeListener
 {
     private static final String LOGTAG = "GeckoPreferences";
 
+    // We have a white background, which makes transitions on
+    // some devices look bad. Don't use transitions on those
+    // devices.
+    private static final boolean NO_TRANSITIONS = HardwareUtils.IS_KINDLE_DEVICE;
+
     private static final String NON_PREF_PREFIX = "android.not_a_preference.";
     public static final String INTENT_EXTRA_RESOURCES = "resource";
     public static String PREFS_HEALTHREPORT_UPLOAD_ENABLED = NON_PREF_PREFIX + "healthreport.uploadEnabled";
 
     private static boolean sIsCharEncodingEnabled = false;
     private boolean mInitialized = false;
     private int mPrefsRequestId = 0;
     private PanelsPreferenceCategory mPanelsPreferenceCategory;
@@ -128,16 +134,29 @@ OnSharedPreferenceChangeListener
     public static final int RESULT_CODE_LOCALE_DID_CHANGE = 7;
 
     /**
      * Track the last locale so we know whether to redisplay.
      */
     private Locale lastLocale = Locale.getDefault();
     private boolean localeSwitchingIsEnabled;
 
+    private void startActivityForResultChoosingTransition(final Intent intent, final int requestCode) {
+        startActivityForResult(intent, requestCode);
+        if (NO_TRANSITIONS) {
+            overridePendingTransition(0, 0);
+        }
+    }
+
+    private void finishChoosingTransition() {
+        finish();
+        if (NO_TRANSITIONS) {
+            overridePendingTransition(0, 0);
+        }
+    }
     private void updateActionBarTitle(int title) {
         if (Build.VERSION.SDK_INT >= 14) {
             final String newTitle = getString(title);
             if (newTitle != null) {
                 Log.v(LOGTAG, "Setting action bar title to " + newTitle);
 
                 final ActionBar actionBar = getActionBar();
                 if (actionBar != null) {
@@ -245,20 +264,20 @@ OnSharedPreferenceChangeListener
         }
 
         // Cause the current fragment to redisplay, the hard way.
         // This avoids nonsense with trying to reach inside fragments and force them
         // to redisplay themselves.
         // We also don't need to update the title.
         final Intent intent = (Intent) getIntent().clone();
         intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
-        startActivityForResult(intent, REQUEST_CODE_PREF_SCREEN);
+        startActivityForResultChoosingTransition(intent, REQUEST_CODE_PREF_SCREEN);
 
         setResult(RESULT_CODE_LOCALE_DID_CHANGE);
-        finish();
+        finishChoosingTransition();
     }
 
     private void checkLocale() {
         final Locale currentLocale = Locale.getDefault();
         Log.v(LOGTAG, "Checking locale: " + currentLocale + " vs " + lastLocale);
         if (currentLocale.equals(lastLocale)) {
             return;
         }
@@ -436,16 +455,25 @@ OnSharedPreferenceChangeListener
         mInitialized = true;
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
             PreferenceScreen screen = getPreferenceScreen();
             mPrefsRequestId = setupPreferences(screen);
         }
     }
 
     @Override
+    public void onBackPressed() {
+        super.onBackPressed();
+
+        if (NO_TRANSITIONS) {
+            overridePendingTransition(0, 0);
+        }
+    }
+
+    @Override
     protected void onDestroy() {
         super.onDestroy();
         EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "Sanitize:Finished");
         if (mPrefsRequestId > 0) {
             PrefsHelper.removeObserver(mPrefsRequestId);
         }
     }
@@ -489,30 +517,33 @@ OnSharedPreferenceChangeListener
     @Override
     public void startActivity(Intent intent) {
         // For settings, we want to be able to pass results up the chain
         // of preference screens so Settings can behave as a single unit.
         // Specifically, when we open a link, we want to back out of all
         // the settings screens.
         // We need to start nested PreferenceScreens withStartActivityForResult().
         // Android doesn't let us do that (see Preference.onClick), so we're overriding here.
-        startActivityForResult(intent, REQUEST_CODE_PREF_SCREEN);
+        startActivityForResultChoosingTransition(intent, REQUEST_CODE_PREF_SCREEN);
     }
 
     @Override
     public void startWithFragment(String fragmentName, Bundle args,
             Fragment resultTo, int resultRequestCode, int titleRes, int shortTitleRes) {
         Log.v(LOGTAG, "Starting with fragment: " + fragmentName + ", title " + titleRes);
 
         // Overriding because we want to use startActivityForResult for Fragment intents.
         Intent intent = onBuildStartFragmentIntent(fragmentName, args, titleRes, shortTitleRes);
         if (resultTo == null) {
-            startActivityForResult(intent, REQUEST_CODE_PREF_SCREEN);
+            startActivityForResultChoosingTransition(intent, REQUEST_CODE_PREF_SCREEN);
         } else {
             resultTo.startActivityForResult(intent, resultRequestCode);
+            if (NO_TRANSITIONS) {
+                overridePendingTransition(0, 0);
+            }
         }
     }
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         // We might have just returned from a settings activity that allows us
         // to switch locales, so reflect any change that occurred.
         checkLocale();
@@ -520,17 +551,17 @@ OnSharedPreferenceChangeListener
         switch (requestCode) {
           case REQUEST_CODE_PREF_SCREEN:
               switch (resultCode) {
               case RESULT_CODE_EXIT_SETTINGS:
                   updateActionBarTitle(R.string.settings_title);
 
                   // Pass this result up to the parent activity.
                   setResult(RESULT_CODE_EXIT_SETTINGS);
-                  finish();
+                  finishChoosingTransition();
                   break;
               }
               break;
 
           case HomePanelPicker.REQUEST_CODE_ADD_PANEL:
               switch (resultCode) {
                   case Activity.RESULT_OK:
                       // Panel installed, refresh panels list.
@@ -685,17 +716,17 @@ OnSharedPreferenceChangeListener
                             return true;
                         }
                     });
                 } else if (PREFS_HOME_ADD_PANEL.equals(key)) {
                     pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                         @Override
                         public boolean onPreferenceClick(Preference preference) {
                             Intent dialogIntent = new Intent(GeckoPreferences.this, HomePanelPicker.class);
-                            startActivityForResult(dialogIntent, HomePanelPicker.REQUEST_CODE_ADD_PANEL);
+                            startActivityForResultChoosingTransition(dialogIntent, HomePanelPicker.REQUEST_CODE_ADD_PANEL);
                             return true;
                         }
                     });
                 }
 
                 // Some Preference UI elements are not actually preferences,
                 // but they require a key to work correctly. For example,
                 // "Clear private data" requires a key for its state to be
@@ -735,17 +766,17 @@ OnSharedPreferenceChangeListener
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:GetVisible", null));
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         int itemId = item.getItemId();
         switch (itemId) {
             case android.R.id.home:
-                finish();
+                finishChoosingTransition();
                 return true;
         }
 
         // Generated R.id.* apparently aren't constant expressions, so they can't be switched.
         if (itemId == R.id.restore_defaults) {
             restoreDefaultSearchEngines();
             return true;
        }
@@ -1002,17 +1033,17 @@ OnSharedPreferenceChangeListener
 
         if (preference instanceof ListPreference) {
             // We need to find the entry for the new value
             int newIndex = ((ListPreference) preference).findIndexOfValue((String) newValue);
             CharSequence newEntry = ((ListPreference) preference).getEntries()[newIndex];
             ((ListPreference) preference).setSummary(newEntry);
         } else if (preference instanceof LinkPreference) {
             setResult(RESULT_CODE_EXIT_SETTINGS);
-            finish();
+            finishChoosingTransition();
         } else if (preference instanceof FontSizePreference) {
             final FontSizePreference fontSizePref = (FontSizePreference) preference;
             fontSizePref.setSummary(fontSizePref.getSavedFontSizeName());
         }
 
         return true;
     }
 
--- a/mobile/android/base/preferences/SyncPreference.java
+++ b/mobile/android/base/preferences/SyncPreference.java
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.preferences;
 
 import org.mozilla.gecko.fxa.activities.FxAccountGetStartedActivity;
 import org.mozilla.gecko.sync.setup.SyncAccounts;
 import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity;
+import org.mozilla.gecko.util.HardwareUtils;
 
 import android.content.Context;
 import android.content.Intent;
 import android.preference.Preference;
 import android.util.AttributeSet;
 
 class SyncPreference extends Preference {
     private static final boolean DEFAULT_TO_FXA = true;
@@ -34,16 +35,21 @@ class SyncPreference extends Preference 
         }
         Intent intent = new Intent(mContext, SetupSyncActivity.class);
         mContext.startActivity(intent);
     }
 
     private void launchFxASetup() {
         Intent intent = new Intent(mContext, FxAccountGetStartedActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        if (HardwareUtils.IS_KINDLE_DEVICE) {
+            intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+        }
+
         mContext.startActivity(intent);
     }
 
     @Override
     protected void onClick() {
         // If we're not defaulting to FxA, just do what we've always done.
         if (!DEFAULT_TO_FXA) {
             openSync11Settings();
--- a/mobile/android/base/util/HardwareUtils.java
+++ b/mobile/android/base/util/HardwareUtils.java
@@ -25,16 +25,20 @@ public final class HardwareUtils {
     // xpcom/base/nsMemoryImpl.cpp) and should only be used in cases
     // where we can't depend on Gecko to be up and running e.g. show/hide
     // reading list capabilities in HomePager.
     private static final int LOW_MEMORY_THRESHOLD_MB = 384;
 
     // Number of bytes of /proc/meminfo to read in one go.
     private static final int MEMINFO_BUFFER_SIZE_BYTES = 256;
 
+    private static final boolean IS_AMAZON_DEVICE = Build.MANUFACTURER.equalsIgnoreCase("Amazon");
+    public static final boolean IS_KINDLE_DEVICE = IS_AMAZON_DEVICE &&
+                                                   (Build.MODEL.equals("Kindle Fire") ||
+                                                    Build.MODEL.startsWith("KF"));
     private static volatile int sTotalRAM = -1;
 
     private static volatile boolean sInited;
 
     // These are all set once, during init.
     private static volatile boolean sIsLargeTablet;
     private static volatile boolean sIsSmallTablet;
     private static volatile boolean sIsTelevision;