Bug 1123102 - Always create reading list panel, regardless of device memory capabilities. r=nalexander
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Fri, 13 Feb 2015 15:55:18 -0800
changeset 256747 78bb737b85eaac4923cb699f7796c9125ad00178
parent 256746 89a1843b77337229bccd2ee50e0e8d5b289b35d0
child 256748 1fc897448cada5c9c917cb5f0dc4e46d27847033
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs1123102
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 1123102 - Always create reading list panel, regardless of device memory capabilities. r=nalexander
mobile/android/base/home/HomeConfigPrefsBackend.java
mobile/android/base/overlays/ui/ShareDialog.java
mobile/android/base/util/HardwareUtils.java
--- a/mobile/android/base/home/HomeConfigPrefsBackend.java
+++ b/mobile/android/base/home/HomeConfigPrefsBackend.java
@@ -31,17 +31,17 @@ import android.content.SharedPreferences
 import android.support.v4.content.LocalBroadcastManager;
 import android.text.TextUtils;
 import android.util.Log;
 
 class HomeConfigPrefsBackend implements HomeConfigBackend {
     private static final String LOGTAG = "GeckoHomeConfigBackend";
 
     // Increment this to trigger a migration.
-    private static final int VERSION = 2;
+    private static final int VERSION = 3;
 
     // This key was originally used to store only an array of panel configs.
     private static final String PREFS_CONFIG_KEY_OLD = "home_panels";
 
     // This key is now used to store a version number with the array of panel configs.
     private static final String PREFS_CONFIG_KEY = "home_panels_with_version";
 
     // Keys used with JSON object stored in prefs.
@@ -68,22 +68,17 @@ class HomeConfigPrefsBackend implements 
 
     private State loadDefaultConfig() {
         final ArrayList<PanelConfig> panelConfigs = new ArrayList<PanelConfig>();
 
         panelConfigs.add(createBuiltinPanelConfig(mContext, PanelType.TOP_SITES,
                                                   EnumSet.of(PanelConfig.Flags.DEFAULT_PANEL)));
 
         panelConfigs.add(createBuiltinPanelConfig(mContext, PanelType.BOOKMARKS));
-
-        // We disable reader mode support on low memory devices. Hence the
-        // reading list panel should not show up on such devices.
-        if (!HardwareUtils.isLowMemoryPlatform()) {
-            panelConfigs.add(createBuiltinPanelConfig(mContext, PanelType.READING_LIST));
-        }
+        panelConfigs.add(createBuiltinPanelConfig(mContext, PanelType.READING_LIST));
 
         final PanelConfig historyEntry = createBuiltinPanelConfig(mContext, PanelType.HISTORY);
         final PanelConfig recentTabsEntry = createBuiltinPanelConfig(mContext, PanelType.RECENT_TABS);
 
         // We disable Synced Tabs for guest mode profiles.
         final PanelConfig remoteTabsEntry;
         if (RestrictedProfiles.isAllowed(mContext, RestrictedProfiles.Restriction.DISALLOW_MODIFY_ACCOUNTS)) {
             remoteTabsEntry = createBuiltinPanelConfig(mContext, PanelType.REMOTE_TABS);
@@ -169,16 +164,41 @@ class HomeConfigPrefsBackend implements 
         // Maybe add the new panel to the back of the array.
         if ((isPhone && positionOnPhones == Position.BACK) ||
             (isTablet && positionOnTablets == Position.BACK)) {
             jsonPanels.put(jsonPanelConfig);
         }
     }
 
     /**
+     * Checks to see if the reading list panel already exists.
+     *
+     * @param jsonPanels JSONArray array representing the curent set of panel configs.
+     *
+     * @return boolean Whether or not the reading list panel exists.
+     */
+    private static boolean readingListPanelExists(JSONArray jsonPanels) {
+        final int count = jsonPanels.length();
+        for (int i = 0; i < count; i++) {
+            try {
+                final JSONObject jsonPanelConfig = jsonPanels.getJSONObject(i);
+                final PanelConfig panelConfig = new PanelConfig(jsonPanelConfig);
+                if (panelConfig.getType() == PanelType.READING_LIST) {
+                    return true;
+                }
+            } catch (Exception e) {
+                // It's okay to ignore this exception, since an invalid reading list
+                // panel config is equivalent to no reading list panel.
+                Log.e(LOGTAG, "Exception loading PanelConfig from JSON", e);
+            }
+        }
+        return false;
+    }
+
+    /**
      * Migrates JSON config data storage.
      *
      * @param context Context used to get shared preferences and create built-in panel.
      * @param jsonString String currently stored in preferences.
      *
      * @return JSONArray array representing new set of panel configs.
      */
     private static synchronized JSONArray maybePerformMigration(Context context, String jsonString) throws JSONException {
@@ -226,16 +246,29 @@ class HomeConfigPrefsBackend implements 
                     prefsEditor.remove(PREFS_CONFIG_KEY_OLD);
                     break;
 
                 case 2:
                     // Add "Remote Tabs"/"Synced Tabs" panel.
                     addBuiltinPanelConfig(context, jsonPanels,
                             PanelType.REMOTE_TABS, Position.FRONT, Position.BACK);
                     break;
+
+                case 3:
+                    // Add the "Reading List" panel if it does not exist. At one time,
+                    // the Reading List panel was shown only to devices that were not
+                    // considered "low memory". Now, we expose the panel to all devices.
+                    // This migration should only occur for "low memory" devices.
+                    // Note: This will not agree with the default configuration, which
+                    // has REMOTE_TABS after READING_LIST on some devices.
+                    if (!readingListPanelExists(jsonPanels)) {
+                        addBuiltinPanelConfig(context, jsonPanels,
+                                PanelType.READING_LIST, Position.BACK, Position.BACK);
+                    }
+                    break;
             }
         }
 
         // Save the new panel config and the new version number.
         final JSONObject newJson = new JSONObject();
         newJson.put(JSON_KEY_PANELS, jsonPanels);
         newJson.put(JSON_KEY_VERSION, VERSION);
 
--- a/mobile/android/base/overlays/ui/ShareDialog.java
+++ b/mobile/android/base/overlays/ui/ShareDialog.java
@@ -17,17 +17,16 @@ import org.mozilla.gecko.TelemetryContra
 import org.mozilla.gecko.db.LocalBrowserDB;
 import org.mozilla.gecko.overlays.OverlayConstants;
 import org.mozilla.gecko.overlays.service.OverlayActionService;
 import org.mozilla.gecko.overlays.service.sharemethods.ParcelableClientRecord;
 import org.mozilla.gecko.overlays.service.sharemethods.SendTab;
 import org.mozilla.gecko.overlays.service.sharemethods.ShareMethod;
 import org.mozilla.gecko.sync.setup.activities.WebURLFinder;
 import org.mozilla.gecko.mozglue.ContextUtils;
-import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.UIAsyncTask;
 
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -209,24 +208,18 @@ public class ShareDialog extends Locales
         // Send tab.
         SendTabList sendTabList = (SendTabList) findViewById(R.id.overlay_send_tab_btn);
 
         // Register ourselves as both the listener and the context for the Adapter.
         SendTabDeviceListArrayAdapter adapter = new SendTabDeviceListArrayAdapter(this, this);
         sendTabList.setAdapter(adapter);
         sendTabList.setSendTabTargetSelectedListener(this);
 
-        // If we're a low memory device, just hide the reading list button. Otherwise, configure it.
         final OverlayDialogButton readinglistBtn = (OverlayDialogButton) findViewById(R.id.overlay_share_reading_list_btn);
 
-        if (HardwareUtils.isLowMemoryPlatform()) {
-            readinglistBtn.setVisibility(View.GONE);
-            return;
-        }
-
         final String readingListEnabledLabel = resources.getString(R.string.overlay_share_reading_list_btn_label);
         final Drawable readingListEnabledIcon = resources.getDrawable(R.drawable.overlay_readinglist_icon);
         readinglistBtn.setEnabledLabelAndIcon(readingListEnabledLabel, readingListEnabledIcon);
 
         final String readingListDisabledLabel = resources.getString(R.string.overlay_share_reading_list_btn_label_already);
         final Drawable readingListDisabledIcon = resources.getDrawable(R.drawable.overlay_readinglist_already_icon);
         readinglistBtn.setDisabledLabelAndIcon(readingListDisabledLabel, readingListDisabledIcon);
 
--- a/mobile/android/base/util/HardwareUtils.java
+++ b/mobile/android/base/util/HardwareUtils.java
@@ -12,24 +12,16 @@ import android.content.pm.PackageManager
 import android.content.res.Configuration;
 import android.os.Build;
 import android.util.Log;
 import android.view.ViewConfiguration;
 
 public final class HardwareUtils {
     private static final String LOGTAG = "GeckoHardwareUtils";
 
-    // Minimum memory threshold for a device to be considered
-    // a low memory platform (see isLowMemoryPlatform). This value
-    // has be in sync with Gecko's equivalent threshold (defined in
-    // 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;
-
     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 boolean sInited;
 
     // These are all set once, during init.
@@ -91,22 +83,9 @@ public final class HardwareUtils {
 
     public static boolean hasMenuButton() {
         return sHasMenuButton;
     }
 
     public static int getMemSize() {
         return SysInfo.getMemSize();
     }
-
-    public static boolean isLowMemoryPlatform() {
-        final int memSize = getMemSize();
-
-        // Fallback to false if we fail to read meminfo
-        // for some reason.
-        if (memSize == 0) {
-            Log.w(LOGTAG, "Could not compute system memory. Falling back to isLowMemoryPlatform = false.");
-            return false;
-        }
-
-        return memSize < LOW_MEMORY_THRESHOLD_MB;
-    }
 }