Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java

Issue 1989283002: Upstream: Launch WebApkActivity from WebAPK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nits. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..2757bbc491d5d42b410d0ab54eebb3678df1b49d 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
@@ -9,9 +9,11 @@ import android.content.SharedPreferences;
import android.os.SystemClock;
import android.util.Log;
+import org.chromium.base.ContextUtils;
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,7 +22,11 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
- * Manages a rotating LRU buffer of WebappActivities to assign webapps to.
+ * Before Lollipop, the only way to create multiple retargetable instances of the same Activity
+ * was to explicitly define them in the Manifest. Given that the user can potentially have an
+ * unlimited number of shortcuts for launching these Activities, we have to actively assign
+ * shortcuts when they launch. Activities are reused in order of when they were last used, with
+ * the least recently used ones reassigned first.
*
* 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.
@@ -63,24 +69,38 @@ 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",
+ "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_TYPE_COUNT = 2;
- private static ActivityAssigner sInstance;
+ private static final Object LOCK = new Object();
+ private static List<ActivityAssigner> sInstances;
private final Context mContext;
private final List<ActivityEntry> mActivityList;
+ // The type index of the Activities managed. Either {@link WEBAPP_ACTIVITY_INDEX} or
+ // {@link WEBAPK_ACTIVITY_INDEX}.
+ private final int mActivityTypeIndex;
/**
* 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_TYPE_COUNT; ++i) {
+ context.getSharedPreferences(PREF_PACKAGE[i], Context.MODE_PRIVATE);
+ }
}
static class ActivityEntry {
@@ -95,26 +115,32 @@ public class ActivityAssigner {
/**
* Returns the singleton instance, creating it if necessary.
+ * @param webappId The app ID.
*/
- public static ActivityAssigner instance(Context context) {
+ public static ActivityAssigner instance(String webappId) {
ThreadUtils.assertOnUiThread();
- if (sInstance == null) {
- sInstance = new ActivityAssigner(context);
+ synchronized (LOCK) {
+ if (sInstances == null) {
+ sInstances = new ArrayList<ActivityAssigner>(ACTIVITY_TYPE_COUNT);
+ for (int i = 0; i < ACTIVITY_TYPE_COUNT; ++i) {
+ sInstances.add(new ActivityAssigner(i));
+ }
+ }
}
- return sInstance;
+ return sInstances.get(ActivityAssigner.getIndex(webappId));
}
- private ActivityAssigner(Context context) {
- mContext = context.getApplicationContext();
+ private ActivityAssigner(int activityTypeIndex) {
+ mContext = ContextUtils.getApplicationContext();
+ mActivityTypeIndex = activityTypeIndex;
mActivityList = new ArrayList<ActivityEntry>();
-
restoreActivityList();
}
/**
- * Assigns the webapp with the given ID to one of the available WebappActivities.
- * If we know that the webapp was previously launched in one of the Activities, re-use it.
- * Otherwise, take the least recently used WebappActivity ID and use that.
+ * Assigns the app with the given ID to one of the available Activity instances.
+ * If we know that the app was previously launched in one of the Activities, re-use it.
+ * Otherwise, take the least recently used ID and use that.
* @param webappId ID of the webapp.
* @return Index of the Activity to use for the webapp.
*/
@@ -134,6 +160,15 @@ public class ActivityAssigner {
}
/**
+ * Returns {@link WEBAPP_ACTIVITY_INDEX} for WebappActivity, {@link WEBAPK_ACTIVITY_INDEX} for
+ * WebApkActivity whose webappId starts with "webapk:".
+ */
+ static 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.
@@ -153,10 +188,10 @@ public class ActivityAssigner {
}
/**
- * 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 an Activity to the back of the queue, indicating that the app is still in use and
+ * shouldn't be killed.
+ * @param activityIndex Index of the Activity in the LRU buffer.
+ * @param webappId The ID of the app being shown in the Activity.
*/
void markActivityUsed(int activityIndex, String webappId) {
// Find the entry corresponding to the Activity.
@@ -167,7 +202,7 @@ public class ActivityAssigner {
return;
}
- // We have to reassign the webapp ID in case WebappActivities get repurposed.
+ // We have to reassign the app ID in case Activities get repurposed.
ActivityEntry updatedEntry = new ActivityEntry(activityIndex, webappId);
mActivityList.remove(elementIndex);
mActivityList.add(updatedEntry);
@@ -189,7 +224,7 @@ public class ActivityAssigner {
}
/**
- * Returns the current mapping between Activities and webapps.
+ * Returns the current mapping between Activities and apps.
*/
@VisibleForTesting
List<ActivityEntry> getEntries() {
@@ -197,9 +232,17 @@ public class ActivityAssigner {
}
/**
- * Restores/creates the mapping between webapps and WebappActivities.
+ * Returns the type index of the Activities managed.
+ */
+ @VisibleForTesting
+ int getActivityTypeIndex() {
+ return mActivityTypeIndex;
+ }
+
+ /**
+ * Restores/creates the mapping between apps and activities.
* The logic is slightly complicated to future-proof against situations where the number of
- * WebappActivities is changed.
+ * Activity is changed.
*/
private void restoreActivityList() {
boolean isMapDirty = false;
@@ -215,10 +258,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[mActivityTypeIndex],
+ 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[mActivityTypeIndex], 0);
try {
RecordHistogram.recordTimesHistogram("Android.StrictMode.WebappSharedPrefs",
SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS);
@@ -227,8 +271,8 @@ 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[mActivityTypeIndex] + i;
+ String currentWebappIdPref = PREF_WEBAPP_ID[mActivityTypeIndex] + i;
int activityIndex = prefs.getInt(currentActivityIndexPref, i);
String webappId = prefs.getString(currentWebappIdPref, null);
@@ -253,7 +297,7 @@ public class ActivityAssigner {
}
}
- // Add entries for any missing WebappActivities.
+ // Add entries for any missing Activities.
for (Integer availableIndex : availableWebapps) {
ActivityEntry entry = new ActivityEntry(availableIndex, null);
mActivityList.add(entry);
@@ -266,16 +310,17 @@ public class ActivityAssigner {
}
/**
- * Saves the mapping between webapps and WebappActivities.
+ * Saves the mapping between apps and Activities.
*/
private void storeActivityList() {
- SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE);
+ SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE[mActivityTypeIndex],
+ Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.clear();
- editor.putInt(PREF_NUM_SAVED_ENTRIES, mActivityList.size());
+ editor.putInt(PREF_NUM_SAVED_ENTRIES[mActivityTypeIndex], mActivityList.size());
for (int i = 0; i < mActivityList.size(); ++i) {
- String currentActivityIndexPref = PREF_ACTIVITY_INDEX + i;
- String currentWebappIdPref = PREF_WEBAPP_ID + i;
+ String currentActivityIndexPref = PREF_ACTIVITY_INDEX[mActivityTypeIndex] + i;
+ String currentWebappIdPref = PREF_WEBAPP_ID[mActivityTypeIndex] + i;
editor.putInt(currentActivityIndexPref, mActivityList.get(i).mActivityIndex);
editor.putString(currentWebappIdPref, mActivityList.get(i).mWebappId);
}

Powered by Google App Engine
This is Rietveld 408576698