Bug 1123102 - Always create reading list panel, regardless of device memory capabilities draft
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Fri, 13 Feb 2015 15:55:18 -0800
changeset 242753 3f4e9eb103a8734a379d36fe4acdf87d15b52bd8
parent 242649 0b63903a6f41f75a8edbcc136541490289598da6
child 505334 7b0d96cf431130bc4dd8cc906f3b4bce8230bf18
push id687
push usermleibovic@mozilla.com
push dateFri, 13 Feb 2015 23:59:19 +0000
bugs1123102
milestone38.0a1
Bug 1123102 - Always create reading list panel, regardless of device memory capabilities
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,39 @@ 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) {
+                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 +244,25 @@ 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.
+                    // This migration should only happen for low memory 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;
@@ -212,21 +211,16 @@ public class ShareDialog extends Locales
         // 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;
-    }
 }