Bug 1260321 - Follow-up: Migrate users with customized panels to combined history panel. r=sebastian
MozReview-Commit-ID: 6SQ7nuZhCe0
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
@@ -289,16 +289,20 @@ public final class HomeConfig {
public int getViewCount() {
return (mViews != null ? mViews.size() : 0);
}
public ViewConfig getViewAt(int index) {
return (mViews != null ? mViews.get(index) : null);
}
+ public EnumSet<Flags> getFlags() {
+ return mFlags.clone();
+ }
+
public boolean isDynamic() {
return (mType == PanelType.DYNAMIC);
}
public boolean isDefault() {
return mFlags.contains(Flags.DEFAULT_PANEL);
}
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomeConfigPrefsBackend.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/HomeConfigPrefsBackend.java
@@ -15,34 +15,32 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.home.HomeConfig.HomeConfigBackend;
import org.mozilla.gecko.home.HomeConfig.OnReloadListener;
import org.mozilla.gecko.home.HomeConfig.PanelConfig;
import org.mozilla.gecko.home.HomeConfig.PanelType;
import org.mozilla.gecko.home.HomeConfig.State;
-import org.mozilla.gecko.restrictions.Restrictable;
-import org.mozilla.gecko.restrictions.Restrictions;
import org.mozilla.gecko.util.HardwareUtils;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
public class HomeConfigPrefsBackend implements HomeConfigBackend {
private static final String LOGTAG = "GeckoHomeConfigBackend";
// Increment this to trigger a migration.
- private static final int VERSION = 3;
+ private static final int VERSION = 4;
// This key was originally used to store only an array of panel configs.
public 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.
public static final String PREFS_CONFIG_KEY = "home_panels_with_version";
// Keys used with JSON object stored in prefs.
@@ -142,16 +140,81 @@ public class HomeConfigPrefsBackend impl
// Maybe add the new panel to the back of the array.
if ((isPhone && positionOnPhones == Position.BACK) ||
(isTablet && positionOnTablets == Position.BACK)) {
jsonPanels.put(jsonPanelConfig);
}
}
/**
+ * Updates the panels to combine the History and Sync panels into the (Combined) History panel.
+ *
+ * Tries to replace the History panel with the Combined History panel if visible, or falls back to
+ * replacing the Sync panel if it's visible. That way, we minimize panel reordering during a migration.
+ * @param context Android context
+ * @param jsonPanels array of original JSON panels
+ * @return new array of updated JSON panels
+ * @throws JSONException
+ */
+ private static JSONArray combineHistoryAndSyncPanels(Context context, JSONArray jsonPanels) throws JSONException {
+ EnumSet<PanelConfig.Flags> historyFlags = null;
+ EnumSet<PanelConfig.Flags> syncFlags = null;
+
+ int historyIndex = -1;
+ int syncIndex = -1;
+
+ // Determine state and location of History and Sync panels.
+ for (int i = 0; i < jsonPanels.length(); i++) {
+ JSONObject panelObj = jsonPanels.getJSONObject(i);
+ final PanelConfig panelConfig = new PanelConfig(panelObj);
+ final PanelType type = panelConfig.getType();
+ if (type == PanelType.HISTORY) {
+ historyIndex = i;
+ historyFlags = panelConfig.getFlags();
+ } else if (type == PanelType.REMOTE_TABS) {
+ syncIndex = i;
+ syncFlags = panelConfig.getFlags();
+ }
+ }
+
+ if (historyIndex == -1 || syncIndex == -1) {
+ throw new IllegalArgumentException("Missing default panels");
+ }
+
+ PanelConfig newPanel;
+ int replaceIndex;
+ int removeIndex;
+ if (historyFlags.contains(PanelConfig.Flags.DISABLED_PANEL) && !syncFlags.contains(PanelConfig.Flags.DISABLED_PANEL)) {
+ // Replace the Sync panel if it's visible and the History panel is disabled.
+ replaceIndex = syncIndex;
+ removeIndex = historyIndex;
+ newPanel = createBuiltinPanelConfig(context, PanelType.COMBINED_HISTORY, syncFlags);
+ } else {
+ // Otherwise, just replace the History panel.
+ replaceIndex = historyIndex;
+ removeIndex = syncIndex;
+ newPanel = createBuiltinPanelConfig(context, PanelType.COMBINED_HISTORY, historyFlags);
+ }
+
+ // Copy the array with updated panel and removed panel.
+ final JSONArray newArray = new JSONArray();
+ for (int i = 0; i < jsonPanels.length(); i++) {
+ if (i == replaceIndex) {
+ newArray.put(newPanel.toJSON());
+ } else if (i == removeIndex) {
+ continue;
+ } else {
+ newArray.put(jsonPanels.get(i));
+ }
+ }
+
+ return newArray;
+ }
+
+ /**
* 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();
@@ -184,17 +247,17 @@ public class HomeConfigPrefsBackend impl
if (sMigrationDone) {
final JSONObject json = new JSONObject(jsonString);
return json.getJSONArray(JSON_KEY_PANELS);
}
// Make sure we only do this version check once.
sMigrationDone = true;
- final JSONArray jsonPanels;
+ JSONArray jsonPanels;
final int version;
final SharedPreferences prefs = GeckoSharedPrefs.forProfile(context);
if (prefs.contains(PREFS_CONFIG_KEY_OLD)) {
// Our original implementation did not contain versioning, so this is implicitly version 0.
jsonPanels = new JSONArray(jsonString);
version = 0;
} else {
@@ -237,16 +300,23 @@ public class HomeConfigPrefsBackend impl
// 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;
+
+ case 4:
+ // Combine the History and Sync panels. In order to minimize an unexpected reordering
+ // of panels, we try to replace the History panel if it's visible, and fall back to
+ // the Sync panel if that's visible.
+ jsonPanels = combineHistoryAndSyncPanels(context, jsonPanels);
+ 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);