Index: chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java |
index c01923984a7ed61d439d20aa2a7c4520ad5416ea..9ae5dcb543ad7b802e05dcf7b6af4c7d2efb84d9 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java |
@@ -12,6 +12,7 @@ import android.util.Log; |
import org.chromium.base.ThreadUtils; |
import org.chromium.base.VisibleForTesting; |
import org.chromium.base.metrics.RecordHistogram; |
+import org.chromium.webapk.lib.common.WebApkConstants; |
import java.util.ArrayList; |
import java.util.HashSet; |
@@ -20,18 +21,21 @@ import java.util.Set; |
import java.util.concurrent.TimeUnit; |
/** |
- * Manages a rotating LRU buffer of WebappActivities to assign webapps to. |
+ * Manages two rotating LRU buffers, one for WebappActivities, and the other one for |
+ * WebApkActivities to assign webapps to. |
* |
gone
2016/05/25 21:50:14
Don't need to / everything, especially since you l
|
- * In order to accommodate a limited number of WebappActivities with a potentially unlimited number |
- * of webapps, we have to rotate the available WebappActivities between the webapps we start up. |
+ * In order to accommodate a limited number of WebappActivitiess/WebApkActivities with a |
+ * potentially unlimited number of webapps, we have to rotate the available |
+ * WebappActivities/WebApkActivities between the webapps we start up. |
* Activities are reused in order of when they were last used, with the least recently used |
* ones culled first. |
* |
* It is impossible to know whether Tasks have been removed from the Recent Task list without the |
* GET_TASKS permission. As a result, the list of Activities inside the Recent Task list will |
* be highly unlikely to match the list maintained in memory. Instead, we store the mapping as it |
- * was the last time we changed it, which allows us to launch webapps in the WebappActivity they |
- * were most recently associated with in cases where a user restarts a webapp from the Recent Tasks. |
+ * was the last time we changed it, which allows us to launch webapps in the |
+ * WebappActivity/WebApkActivity they were most recently associated with in cases where a user |
+ * restarts a webapp from the Recent Tasks. |
* Note that in situations where the user manually clears the app data, we will again have an |
* incorrect mapping. |
* |
@@ -63,24 +67,34 @@ public class ActivityAssigner { |
// Don't ever change the package. Left for backwards compatibility. |
@VisibleForTesting |
- static final String PREF_PACKAGE = "com.google.android.apps.chrome.webapps"; |
- static final String PREF_NUM_SAVED_ENTRIES = "ActivityAssigner.numSavedEntries"; |
- static final String PREF_ACTIVITY_INDEX = "ActivityAssigner.activityIndex"; |
- static final String PREF_WEBAPP_ID = "ActivityAssigner.webappId"; |
+ static final String PREF_PACKAGE[] = {"com.google.android.apps.chrome.webapps", |
gone
2016/05/25 21:50:13
Don't bother with adding another package -- just u
|
+ "com.google.android.apps.chrome.webapps.webapk"}; |
+ |
+ static final String PREF_NUM_SAVED_ENTRIES[] = {"ActivityAssigner.numSavedEntries", |
+ "ActivityAssigner.numSavedEntries.webapk"}; |
+ static final String PREF_ACTIVITY_INDEX[] = {"ActivityAssigner.activityIndex", |
+ "ActivityAssigner.activityIndex.webapk"}; |
+ static final String PREF_WEBAPP_ID[] = {"ActivityAssigner.webappId", |
+ "ActivityAssigner.webappId.webapk"}; |
static final int INVALID_ACTIVITY_INDEX = -1; |
+ static final int WEBAPP_ACTIVITY_INDEX = 0; |
+ static final int WEBAPK_ACTIVITY_INDEX = 1; |
+ static final int ACTIVITY_TYPES = 2; |
gone
2016/05/25 21:50:14
nit: ACTIVITY_TYPE_COUNT
|
private static ActivityAssigner sInstance; |
private final Context mContext; |
- private final List<ActivityEntry> mActivityList; |
+ private final List<ActivityEntry>[] mActivityList; |
/** |
* Pre-load shared prefs to avoid being blocked on the |
* disk access async task in the future. |
*/ |
public static void warmUpSharedPrefs(Context context) { |
- context.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE); |
+ for (int i = 0; i < ACTIVITY_TYPES; ++i) { |
+ context.getSharedPreferences(PREF_PACKAGE[i], Context.MODE_PRIVATE); |
+ } |
} |
static class ActivityEntry { |
@@ -106,15 +120,18 @@ public class ActivityAssigner { |
private ActivityAssigner(Context context) { |
mContext = context.getApplicationContext(); |
- mActivityList = new ArrayList<ActivityEntry>(); |
- |
- restoreActivityList(); |
+ mActivityList = new ArrayList[ACTIVITY_TYPES]; |
+ for (int i = 0; i < mActivityList.length; i++) { |
+ mActivityList[i] = new ArrayList<ActivityEntry>(); |
+ restoreActivityList(i); |
+ } |
} |
/** |
- * Assigns the webapp with the given ID to one of the available WebappActivities. |
+ * Assigns the webapp with the given ID to one of the available |
+ * WebappActivities/WebApkActivities. |
gone
2016/05/25 21:50:13
Assign the app with the given ID to one of the ava
|
* If we know that the webapp was previously launched in one of the Activities, re-use it. |
gone
2016/05/25 21:50:13
webapp -> app
least recently used ID and use that
|
- * Otherwise, take the least recently used WebappActivity ID and use that. |
+ * Otherwise, take the least recently used WebappActivity/WebApkActivity ID and use that. |
* @param webappId ID of the webapp. |
* @return Index of the Activity to use for the webapp. |
*/ |
@@ -124,9 +141,11 @@ public class ActivityAssigner { |
// Allocate the one in the front of the list. |
if (activityIndex == INVALID_ACTIVITY_INDEX) { |
- activityIndex = mActivityList.get(0).mActivityIndex; |
+ // Get index of the LRU buffer depending on the {@link webappId}. |
+ int index = getIndex(webappId); |
+ activityIndex = mActivityList[index].get(0).mActivityIndex; |
ActivityEntry newEntry = new ActivityEntry(activityIndex, webappId); |
- mActivityList.set(0, newEntry); |
+ mActivityList[index].set(0, newEntry); |
} |
markActivityUsed(activityIndex, webappId); |
@@ -134,6 +153,15 @@ public class ActivityAssigner { |
} |
/** |
+ * Returns {@link WEBAPP_ACTIVITY_INDEX} for WebappActivity, {@link WEBAPK_ACTIVITY_INDEX} for |
+ * WebApkActivity whose webappId starts with "webapk:". |
+ */ |
+ int getIndex(String webappId) { |
+ return webappId.startsWith(WebApkConstants.WEBAPK_ID_PREFIX) ? WEBAPK_ACTIVITY_INDEX |
+ : WEBAPP_ACTIVITY_INDEX; |
+ } |
+ |
+ /** |
* Checks if the webapp with the given ID has been assigned to an Activity already. |
* @param webappId ID of the webapp being displayed. |
* @return Index of the Activity for the webapp if assigned, INVALID_ACTIVITY_INDEX otherwise. |
@@ -144,23 +172,25 @@ public class ActivityAssigner { |
} |
// Go backwards in the queue to catch more recent instances of any duplicated webapps. |
- for (int i = mActivityList.size() - 1; i >= 0; i--) { |
- if (webappId.equals(mActivityList.get(i).mWebappId)) { |
- return mActivityList.get(i).mActivityIndex; |
+ int index = getIndex(webappId); |
+ for (int i = mActivityList[index].size() - 1; i >= 0; i--) { |
+ if (webappId.equals(mActivityList[index].get(i).mWebappId)) { |
+ return mActivityList[index].get(i).mActivityIndex; |
} |
} |
return INVALID_ACTIVITY_INDEX; |
} |
/** |
- * Moves a WebappActivity to the back of the queue, indicating that the Webapp is still in use |
- * and shouldn't be killed. |
- * @param activityIndex Index of the WebappActivity. |
- * @param webappId ID of the webapp being shown in the WebappActivity. |
+ * Moves a WebappActivity/WebApkActivity to the back of the queue, indicating that the Webapp |
+ * is still in use and shouldn't be killed. |
+ * @param activityIndex Index of the WebappActivity/WebApkActivity. |
+ * @param webappId ID of the webapp being shown in the WebappActivity/WebApkActivity. |
*/ |
void markActivityUsed(int activityIndex, String webappId) { |
// Find the entry corresponding to the Activity. |
- int elementIndex = findActivityElement(activityIndex); |
+ int index = getIndex(webappId); |
+ int elementIndex = findActivityElement(activityIndex, index); |
if (elementIndex == -1) { |
Log.e(TAG, "Failed to find WebappActivity entry: " + activityIndex + ", " + webappId); |
@@ -169,19 +199,20 @@ public class ActivityAssigner { |
// We have to reassign the webapp ID in case WebappActivities get repurposed. |
ActivityEntry updatedEntry = new ActivityEntry(activityIndex, webappId); |
- mActivityList.remove(elementIndex); |
- mActivityList.add(updatedEntry); |
- storeActivityList(); |
+ mActivityList[index].remove(elementIndex); |
+ mActivityList[index].add(updatedEntry); |
+ storeActivityList(index); |
} |
/** |
* Finds the index of the ActivityElement corresponding to the given activityIndex. |
* @param activityIndex Index of the activity to find. |
+ * @param typeIndex Index of WebappActivities or WebApkActivities in {@link mActivityIndex}. |
* @return The index of the ActivityElement in the activity list, or -1 if it couldn't be found. |
*/ |
- private int findActivityElement(int activityIndex) { |
- for (int elementIndex = 0; elementIndex < mActivityList.size(); elementIndex++) { |
- if (mActivityList.get(elementIndex).mActivityIndex == activityIndex) { |
+ private int findActivityElement(int activityIndex, int typeIndex) { |
+ for (int elementIndex = 0; elementIndex < mActivityList[typeIndex].size(); elementIndex++) { |
+ if (mActivityList[typeIndex].get(elementIndex).mActivityIndex == activityIndex) { |
return elementIndex; |
} |
} |
@@ -192,18 +223,19 @@ public class ActivityAssigner { |
* Returns the current mapping between Activities and webapps. |
*/ |
@VisibleForTesting |
- List<ActivityEntry> getEntries() { |
+ List<ActivityEntry>[] getEntries() { |
return mActivityList; |
} |
/** |
- * Restores/creates the mapping between webapps and WebappActivities. |
+ * Restores/creates the mapping between webapps and WebappActivities/WebApkActivities depending |
+ * on the {@link index}. |
* The logic is slightly complicated to future-proof against situations where the number of |
- * WebappActivities is changed. |
+ * WebappActivities/WebApkActivity is changed. |
*/ |
- private void restoreActivityList() { |
+ private void restoreActivityList(int index) { |
boolean isMapDirty = false; |
- mActivityList.clear(); |
+ mActivityList[index].clear(); |
// Create a Set of indices corresponding to every possible Activity. |
// As ActivityEntries are read, they are and removed from this list to indicate that the |
@@ -215,10 +247,11 @@ public class ActivityAssigner { |
// Restore any entries that were previously saved. If it seems that the preferences have |
// been corrupted somehow, just discard the whole map. |
- SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE); |
+ SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE[index], |
+ Context.MODE_PRIVATE); |
try { |
long time = SystemClock.elapsedRealtime(); |
- final int numSavedEntries = prefs.getInt(PREF_NUM_SAVED_ENTRIES, 0); |
+ final int numSavedEntries = prefs.getInt(PREF_NUM_SAVED_ENTRIES[index], 0); |
try { |
RecordHistogram.recordTimesHistogram("Android.StrictMode.WebappSharedPrefs", |
SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS); |
@@ -227,15 +260,15 @@ public class ActivityAssigner { |
} |
if (numSavedEntries <= NUM_WEBAPP_ACTIVITIES) { |
for (int i = 0; i < numSavedEntries; ++i) { |
- String currentActivityIndexPref = PREF_ACTIVITY_INDEX + i; |
- String currentWebappIdPref = PREF_WEBAPP_ID + i; |
+ String currentActivityIndexPref = PREF_ACTIVITY_INDEX[index] + i; |
+ String currentWebappIdPref = PREF_WEBAPP_ID[index] + i; |
int activityIndex = prefs.getInt(currentActivityIndexPref, i); |
String webappId = prefs.getString(currentWebappIdPref, null); |
ActivityEntry entry = new ActivityEntry(activityIndex, webappId); |
if (availableWebapps.remove(entry.mActivityIndex)) { |
- mActivityList.add(entry); |
+ mActivityList[index].add(entry); |
} else { |
// If the same activity was assigned to two different entries, or if the |
// number of activities changed, discard it and mark that it needs to be |
@@ -246,38 +279,40 @@ public class ActivityAssigner { |
} |
} catch (ClassCastException exception) { |
// Something went wrong reading the preferences. Nuke everything. |
- mActivityList.clear(); |
+ mActivityList[index].clear(); |
availableWebapps.clear(); |
for (int i = 0; i < NUM_WEBAPP_ACTIVITIES; ++i) { |
availableWebapps.add(i); |
} |
} |
- // Add entries for any missing WebappActivities. |
+ // Add entries for any missing WebappActivities/WebApkActivities. |
for (Integer availableIndex : availableWebapps) { |
ActivityEntry entry = new ActivityEntry(availableIndex, null); |
- mActivityList.add(entry); |
+ mActivityList[index].add(entry); |
isMapDirty = true; |
} |
if (isMapDirty) { |
- storeActivityList(); |
+ storeActivityList(index); |
} |
} |
/** |
- * Saves the mapping between webapps and WebappActivities. |
+ * Saves the mapping between webapps and WebappActivities/WebApkActivities depending on the |
+ * {@link index}. |
*/ |
- private void storeActivityList() { |
- SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE); |
+ private void storeActivityList(int index) { |
+ SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE[index], |
+ Context.MODE_PRIVATE); |
SharedPreferences.Editor editor = prefs.edit(); |
editor.clear(); |
- editor.putInt(PREF_NUM_SAVED_ENTRIES, mActivityList.size()); |
- for (int i = 0; i < mActivityList.size(); ++i) { |
- String currentActivityIndexPref = PREF_ACTIVITY_INDEX + i; |
- String currentWebappIdPref = PREF_WEBAPP_ID + i; |
- editor.putInt(currentActivityIndexPref, mActivityList.get(i).mActivityIndex); |
- editor.putString(currentWebappIdPref, mActivityList.get(i).mWebappId); |
+ editor.putInt(PREF_NUM_SAVED_ENTRIES[index], mActivityList[index].size()); |
+ for (int i = 0; i < mActivityList[index].size(); ++i) { |
+ String currentActivityIndexPref = PREF_ACTIVITY_INDEX[index] + i; |
+ String currentWebappIdPref = PREF_WEBAPP_ID[index] + i; |
+ editor.putInt(currentActivityIndexPref, mActivityList[index].get(i).mActivityIndex); |
+ editor.putString(currentWebappIdPref, mActivityList[index].get(i).mWebappId); |
} |
editor.apply(); |
} |