Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
|
gone
2016/05/25 21:50:13
It makes more sense to have two ActivityAssigner i
| |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.webapps; | 5 package org.chromium.chrome.browser.webapps; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.content.SharedPreferences; | 8 import android.content.SharedPreferences; |
| 9 import android.os.SystemClock; | 9 import android.os.SystemClock; |
| 10 import android.util.Log; | 10 import android.util.Log; |
| 11 | 11 |
| 12 import org.chromium.base.ThreadUtils; | 12 import org.chromium.base.ThreadUtils; |
| 13 import org.chromium.base.VisibleForTesting; | 13 import org.chromium.base.VisibleForTesting; |
| 14 import org.chromium.base.metrics.RecordHistogram; | 14 import org.chromium.base.metrics.RecordHistogram; |
| 15 import org.chromium.webapk.lib.common.WebApkConstants; | |
| 15 | 16 |
| 16 import java.util.ArrayList; | 17 import java.util.ArrayList; |
| 17 import java.util.HashSet; | 18 import java.util.HashSet; |
| 18 import java.util.List; | 19 import java.util.List; |
| 19 import java.util.Set; | 20 import java.util.Set; |
| 20 import java.util.concurrent.TimeUnit; | 21 import java.util.concurrent.TimeUnit; |
| 21 | 22 |
| 22 /** | 23 /** |
| 23 * Manages a rotating LRU buffer of WebappActivities to assign webapps to. | 24 * Manages two rotating LRU buffers, one for WebappActivities, and the other one for |
| 25 * WebApkActivities to assign webapps to. | |
| 24 * | 26 * |
|
gone
2016/05/25 21:50:14
Don't need to / everything, especially since you l
| |
| 25 * In order to accommodate a limited number of WebappActivities with a potential ly unlimited number | 27 * In order to accommodate a limited number of WebappActivitiess/WebApkActivitie s with a |
| 26 * of webapps, we have to rotate the available WebappActivities between the weba pps we start up. | 28 * potentially unlimited number of webapps, we have to rotate the available |
| 29 * WebappActivities/WebApkActivities between the webapps we start up. | |
| 27 * Activities are reused in order of when they were last used, with the least re cently used | 30 * Activities are reused in order of when they were last used, with the least re cently used |
| 28 * ones culled first. | 31 * ones culled first. |
| 29 * | 32 * |
| 30 * It is impossible to know whether Tasks have been removed from the Recent Task list without the | 33 * It is impossible to know whether Tasks have been removed from the Recent Task list without the |
| 31 * GET_TASKS permission. As a result, the list of Activities inside the Recent Task list will | 34 * GET_TASKS permission. As a result, the list of Activities inside the Recent Task list will |
| 32 * be highly unlikely to match the list maintained in memory. Instead, we store the mapping as it | 35 * be highly unlikely to match the list maintained in memory. Instead, we store the mapping as it |
| 33 * was the last time we changed it, which allows us to launch webapps in the Web appActivity they | 36 * was the last time we changed it, which allows us to launch webapps in the |
| 34 * were most recently associated with in cases where a user restarts a webapp fr om the Recent Tasks. | 37 * WebappActivity/WebApkActivity they were most recently associated with in case s where a user |
| 38 * restarts a webapp from the Recent Tasks. | |
| 35 * Note that in situations where the user manually clears the app data, we will again have an | 39 * Note that in situations where the user manually clears the app data, we will again have an |
| 36 * incorrect mapping. | 40 * incorrect mapping. |
| 37 * | 41 * |
| 38 * Unless otherwise noted, all methods MUST be called on the UI thread to avoid threading issues. | 42 * Unless otherwise noted, all methods MUST be called on the UI thread to avoid threading issues. |
| 39 * | 43 * |
| 40 * EXAMPLE: | 44 * EXAMPLE: |
| 41 * - 3 Activities are available for assignment (0, 1, 2). | 45 * - 3 Activities are available for assignment (0, 1, 2). |
| 42 * - 4 webapps exist (X, Y, Z, W). | 46 * - 4 webapps exist (X, Y, Z, W). |
| 43 * | 47 * |
| 44 * ACTION EFFECT ACTIVI TY LIST | 48 * ACTION EFFECT ACTIVI TY LIST |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 56 // Don't ever change this. 10 is enough for everyone. | 60 // Don't ever change this. 10 is enough for everyone. |
| 57 static final int NUM_WEBAPP_ACTIVITIES = 10; | 61 static final int NUM_WEBAPP_ACTIVITIES = 10; |
| 58 | 62 |
| 59 // A sanity check limit to ensure that we aren't reading an unreasonable num ber of preferences. | 63 // A sanity check limit to ensure that we aren't reading an unreasonable num ber of preferences. |
| 60 // This number is different from above because the number of WebappActivitie s available may | 64 // This number is different from above because the number of WebappActivitie s available may |
| 61 // change. | 65 // change. |
| 62 static final int MAX_WEBAPP_ACTIVITIES_EVER = 100; | 66 static final int MAX_WEBAPP_ACTIVITIES_EVER = 100; |
| 63 | 67 |
| 64 // Don't ever change the package. Left for backwards compatibility. | 68 // Don't ever change the package. Left for backwards compatibility. |
| 65 @VisibleForTesting | 69 @VisibleForTesting |
| 66 static final String PREF_PACKAGE = "com.google.android.apps.chrome.webapps"; | 70 static final String PREF_PACKAGE[] = {"com.google.android.apps.chrome.webapp s", |
|
gone
2016/05/25 21:50:13
Don't bother with adding another package -- just u
| |
| 67 static final String PREF_NUM_SAVED_ENTRIES = "ActivityAssigner.numSavedEntri es"; | 71 "com.google.android.apps.chrome.webapps.webapk"}; |
| 68 static final String PREF_ACTIVITY_INDEX = "ActivityAssigner.activityIndex"; | 72 |
| 69 static final String PREF_WEBAPP_ID = "ActivityAssigner.webappId"; | 73 static final String PREF_NUM_SAVED_ENTRIES[] = {"ActivityAssigner.numSavedEn tries", |
| 74 "ActivityAssigner.numSavedEntries.webapk"}; | |
| 75 static final String PREF_ACTIVITY_INDEX[] = {"ActivityAssigner.activityIndex ", | |
| 76 "ActivityAssigner.activityIndex.webapk"}; | |
| 77 static final String PREF_WEBAPP_ID[] = {"ActivityAssigner.webappId", | |
| 78 "ActivityAssigner.webappId.webapk"}; | |
| 70 | 79 |
| 71 static final int INVALID_ACTIVITY_INDEX = -1; | 80 static final int INVALID_ACTIVITY_INDEX = -1; |
| 81 static final int WEBAPP_ACTIVITY_INDEX = 0; | |
| 82 static final int WEBAPK_ACTIVITY_INDEX = 1; | |
| 83 static final int ACTIVITY_TYPES = 2; | |
|
gone
2016/05/25 21:50:14
nit: ACTIVITY_TYPE_COUNT
| |
| 72 | 84 |
| 73 private static ActivityAssigner sInstance; | 85 private static ActivityAssigner sInstance; |
| 74 | 86 |
| 75 private final Context mContext; | 87 private final Context mContext; |
| 76 private final List<ActivityEntry> mActivityList; | 88 private final List<ActivityEntry>[] mActivityList; |
| 77 | 89 |
| 78 /** | 90 /** |
| 79 * Pre-load shared prefs to avoid being blocked on the | 91 * Pre-load shared prefs to avoid being blocked on the |
| 80 * disk access async task in the future. | 92 * disk access async task in the future. |
| 81 */ | 93 */ |
| 82 public static void warmUpSharedPrefs(Context context) { | 94 public static void warmUpSharedPrefs(Context context) { |
| 83 context.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE); | 95 for (int i = 0; i < ACTIVITY_TYPES; ++i) { |
| 96 context.getSharedPreferences(PREF_PACKAGE[i], Context.MODE_PRIVATE); | |
| 97 } | |
| 84 } | 98 } |
| 85 | 99 |
| 86 static class ActivityEntry { | 100 static class ActivityEntry { |
| 87 final int mActivityIndex; | 101 final int mActivityIndex; |
| 88 final String mWebappId; | 102 final String mWebappId; |
| 89 | 103 |
| 90 ActivityEntry(int activity, String webapp) { | 104 ActivityEntry(int activity, String webapp) { |
| 91 mActivityIndex = activity; | 105 mActivityIndex = activity; |
| 92 mWebappId = webapp; | 106 mWebappId = webapp; |
| 93 } | 107 } |
| 94 } | 108 } |
| 95 | 109 |
| 96 /** | 110 /** |
| 97 * Returns the singleton instance, creating it if necessary. | 111 * Returns the singleton instance, creating it if necessary. |
| 98 */ | 112 */ |
| 99 public static ActivityAssigner instance(Context context) { | 113 public static ActivityAssigner instance(Context context) { |
| 100 ThreadUtils.assertOnUiThread(); | 114 ThreadUtils.assertOnUiThread(); |
| 101 if (sInstance == null) { | 115 if (sInstance == null) { |
| 102 sInstance = new ActivityAssigner(context); | 116 sInstance = new ActivityAssigner(context); |
| 103 } | 117 } |
| 104 return sInstance; | 118 return sInstance; |
| 105 } | 119 } |
| 106 | 120 |
| 107 private ActivityAssigner(Context context) { | 121 private ActivityAssigner(Context context) { |
| 108 mContext = context.getApplicationContext(); | 122 mContext = context.getApplicationContext(); |
| 109 mActivityList = new ArrayList<ActivityEntry>(); | 123 mActivityList = new ArrayList[ACTIVITY_TYPES]; |
| 110 | 124 for (int i = 0; i < mActivityList.length; i++) { |
| 111 restoreActivityList(); | 125 mActivityList[i] = new ArrayList<ActivityEntry>(); |
| 126 restoreActivityList(i); | |
| 127 } | |
| 112 } | 128 } |
| 113 | 129 |
| 114 /** | 130 /** |
| 115 * Assigns the webapp with the given ID to one of the available WebappActivi ties. | 131 * Assigns the webapp with the given ID to one of the available |
| 132 * WebappActivities/WebApkActivities. | |
|
gone
2016/05/25 21:50:13
Assign the app with the given ID to one of the ava
| |
| 116 * If we know that the webapp was previously launched in one of the Activiti es, re-use it. | 133 * If we know that the webapp was previously launched in one of the Activiti es, re-use it. |
|
gone
2016/05/25 21:50:13
webapp -> app
least recently used ID and use that
| |
| 117 * Otherwise, take the least recently used WebappActivity ID and use that. | 134 * Otherwise, take the least recently used WebappActivity/WebApkActivity ID and use that. |
| 118 * @param webappId ID of the webapp. | 135 * @param webappId ID of the webapp. |
| 119 * @return Index of the Activity to use for the webapp. | 136 * @return Index of the Activity to use for the webapp. |
| 120 */ | 137 */ |
| 121 int assign(String webappId) { | 138 int assign(String webappId) { |
| 122 // Reuse a running Activity with the same ID, if it exists. | 139 // Reuse a running Activity with the same ID, if it exists. |
| 123 int activityIndex = checkIfAssigned(webappId); | 140 int activityIndex = checkIfAssigned(webappId); |
| 124 | 141 |
| 125 // Allocate the one in the front of the list. | 142 // Allocate the one in the front of the list. |
| 126 if (activityIndex == INVALID_ACTIVITY_INDEX) { | 143 if (activityIndex == INVALID_ACTIVITY_INDEX) { |
| 127 activityIndex = mActivityList.get(0).mActivityIndex; | 144 // Get index of the LRU buffer depending on the {@link webappId}. |
| 145 int index = getIndex(webappId); | |
| 146 activityIndex = mActivityList[index].get(0).mActivityIndex; | |
| 128 ActivityEntry newEntry = new ActivityEntry(activityIndex, webappId); | 147 ActivityEntry newEntry = new ActivityEntry(activityIndex, webappId); |
| 129 mActivityList.set(0, newEntry); | 148 mActivityList[index].set(0, newEntry); |
| 130 } | 149 } |
| 131 | 150 |
| 132 markActivityUsed(activityIndex, webappId); | 151 markActivityUsed(activityIndex, webappId); |
| 133 return activityIndex; | 152 return activityIndex; |
| 134 } | 153 } |
| 135 | 154 |
| 136 /** | 155 /** |
| 156 * Returns {@link WEBAPP_ACTIVITY_INDEX} for WebappActivity, {@link WEBAPK_A CTIVITY_INDEX} for | |
| 157 * WebApkActivity whose webappId starts with "webapk:". | |
| 158 */ | |
| 159 int getIndex(String webappId) { | |
| 160 return webappId.startsWith(WebApkConstants.WEBAPK_ID_PREFIX) ? WEBAPK_AC TIVITY_INDEX | |
| 161 : WEBAPP_ACTIVITY_INDEX; | |
| 162 } | |
| 163 | |
| 164 /** | |
| 137 * Checks if the webapp with the given ID has been assigned to an Activity a lready. | 165 * Checks if the webapp with the given ID has been assigned to an Activity a lready. |
| 138 * @param webappId ID of the webapp being displayed. | 166 * @param webappId ID of the webapp being displayed. |
| 139 * @return Index of the Activity for the webapp if assigned, INVALID_ACTIVIT Y_INDEX otherwise. | 167 * @return Index of the Activity for the webapp if assigned, INVALID_ACTIVIT Y_INDEX otherwise. |
| 140 */ | 168 */ |
| 141 int checkIfAssigned(String webappId) { | 169 int checkIfAssigned(String webappId) { |
| 142 if (webappId == null) { | 170 if (webappId == null) { |
| 143 return INVALID_ACTIVITY_INDEX; | 171 return INVALID_ACTIVITY_INDEX; |
| 144 } | 172 } |
| 145 | 173 |
| 146 // Go backwards in the queue to catch more recent instances of any dupli cated webapps. | 174 // Go backwards in the queue to catch more recent instances of any dupli cated webapps. |
| 147 for (int i = mActivityList.size() - 1; i >= 0; i--) { | 175 int index = getIndex(webappId); |
| 148 if (webappId.equals(mActivityList.get(i).mWebappId)) { | 176 for (int i = mActivityList[index].size() - 1; i >= 0; i--) { |
| 149 return mActivityList.get(i).mActivityIndex; | 177 if (webappId.equals(mActivityList[index].get(i).mWebappId)) { |
| 178 return mActivityList[index].get(i).mActivityIndex; | |
| 150 } | 179 } |
| 151 } | 180 } |
| 152 return INVALID_ACTIVITY_INDEX; | 181 return INVALID_ACTIVITY_INDEX; |
| 153 } | 182 } |
| 154 | 183 |
| 155 /** | 184 /** |
| 156 * Moves a WebappActivity to the back of the queue, indicating that the Weba pp is still in use | 185 * Moves a WebappActivity/WebApkActivity to the back of the queue, indicatin g that the Webapp |
| 157 * and shouldn't be killed. | 186 * is still in use and shouldn't be killed. |
| 158 * @param activityIndex Index of the WebappActivity. | 187 * @param activityIndex Index of the WebappActivity/WebApkActivity. |
| 159 * @param webappId ID of the webapp being shown in the WebappActivity. | 188 * @param webappId ID of the webapp being shown in the WebappActivity/WebApk Activity. |
| 160 */ | 189 */ |
| 161 void markActivityUsed(int activityIndex, String webappId) { | 190 void markActivityUsed(int activityIndex, String webappId) { |
| 162 // Find the entry corresponding to the Activity. | 191 // Find the entry corresponding to the Activity. |
| 163 int elementIndex = findActivityElement(activityIndex); | 192 int index = getIndex(webappId); |
| 193 int elementIndex = findActivityElement(activityIndex, index); | |
| 164 | 194 |
| 165 if (elementIndex == -1) { | 195 if (elementIndex == -1) { |
| 166 Log.e(TAG, "Failed to find WebappActivity entry: " + activityIndex + ", " + webappId); | 196 Log.e(TAG, "Failed to find WebappActivity entry: " + activityIndex + ", " + webappId); |
| 167 return; | 197 return; |
| 168 } | 198 } |
| 169 | 199 |
| 170 // We have to reassign the webapp ID in case WebappActivities get repurp osed. | 200 // We have to reassign the webapp ID in case WebappActivities get repurp osed. |
| 171 ActivityEntry updatedEntry = new ActivityEntry(activityIndex, webappId); | 201 ActivityEntry updatedEntry = new ActivityEntry(activityIndex, webappId); |
| 172 mActivityList.remove(elementIndex); | 202 mActivityList[index].remove(elementIndex); |
| 173 mActivityList.add(updatedEntry); | 203 mActivityList[index].add(updatedEntry); |
| 174 storeActivityList(); | 204 storeActivityList(index); |
| 175 } | 205 } |
| 176 | 206 |
| 177 /** | 207 /** |
| 178 * Finds the index of the ActivityElement corresponding to the given activit yIndex. | 208 * Finds the index of the ActivityElement corresponding to the given activit yIndex. |
| 179 * @param activityIndex Index of the activity to find. | 209 * @param activityIndex Index of the activity to find. |
| 210 * @param typeIndex Index of WebappActivities or WebApkActivities in {@link mActivityIndex}. | |
| 180 * @return The index of the ActivityElement in the activity list, or -1 if i t couldn't be found. | 211 * @return The index of the ActivityElement in the activity list, or -1 if i t couldn't be found. |
| 181 */ | 212 */ |
| 182 private int findActivityElement(int activityIndex) { | 213 private int findActivityElement(int activityIndex, int typeIndex) { |
| 183 for (int elementIndex = 0; elementIndex < mActivityList.size(); elementI ndex++) { | 214 for (int elementIndex = 0; elementIndex < mActivityList[typeIndex].size( ); elementIndex++) { |
| 184 if (mActivityList.get(elementIndex).mActivityIndex == activityIndex) { | 215 if (mActivityList[typeIndex].get(elementIndex).mActivityIndex == act ivityIndex) { |
| 185 return elementIndex; | 216 return elementIndex; |
| 186 } | 217 } |
| 187 } | 218 } |
| 188 return -1; | 219 return -1; |
| 189 } | 220 } |
| 190 | 221 |
| 191 /** | 222 /** |
| 192 * Returns the current mapping between Activities and webapps. | 223 * Returns the current mapping between Activities and webapps. |
| 193 */ | 224 */ |
| 194 @VisibleForTesting | 225 @VisibleForTesting |
| 195 List<ActivityEntry> getEntries() { | 226 List<ActivityEntry>[] getEntries() { |
| 196 return mActivityList; | 227 return mActivityList; |
| 197 } | 228 } |
| 198 | 229 |
| 199 /** | 230 /** |
| 200 * Restores/creates the mapping between webapps and WebappActivities. | 231 * Restores/creates the mapping between webapps and WebappActivities/WebApkA ctivities depending |
| 232 * on the {@link index}. | |
| 201 * The logic is slightly complicated to future-proof against situations wher e the number of | 233 * The logic is slightly complicated to future-proof against situations wher e the number of |
| 202 * WebappActivities is changed. | 234 * WebappActivities/WebApkActivity is changed. |
| 203 */ | 235 */ |
| 204 private void restoreActivityList() { | 236 private void restoreActivityList(int index) { |
| 205 boolean isMapDirty = false; | 237 boolean isMapDirty = false; |
| 206 mActivityList.clear(); | 238 mActivityList[index].clear(); |
| 207 | 239 |
| 208 // Create a Set of indices corresponding to every possible Activity. | 240 // Create a Set of indices corresponding to every possible Activity. |
| 209 // As ActivityEntries are read, they are and removed from this list to i ndicate that the | 241 // As ActivityEntries are read, they are and removed from this list to i ndicate that the |
| 210 // Activity has already been assigned. | 242 // Activity has already been assigned. |
| 211 Set<Integer> availableWebapps = new HashSet<Integer>(); | 243 Set<Integer> availableWebapps = new HashSet<Integer>(); |
| 212 for (int i = 0; i < NUM_WEBAPP_ACTIVITIES; ++i) { | 244 for (int i = 0; i < NUM_WEBAPP_ACTIVITIES; ++i) { |
| 213 availableWebapps.add(i); | 245 availableWebapps.add(i); |
| 214 } | 246 } |
| 215 | 247 |
| 216 // Restore any entries that were previously saved. If it seems that the preferences have | 248 // Restore any entries that were previously saved. If it seems that the preferences have |
| 217 // been corrupted somehow, just discard the whole map. | 249 // been corrupted somehow, just discard the whole map. |
| 218 SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE, Co ntext.MODE_PRIVATE); | 250 SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE[ind ex], |
| 251 Context.MODE_PRIVATE); | |
| 219 try { | 252 try { |
| 220 long time = SystemClock.elapsedRealtime(); | 253 long time = SystemClock.elapsedRealtime(); |
| 221 final int numSavedEntries = prefs.getInt(PREF_NUM_SAVED_ENTRIES, 0); | 254 final int numSavedEntries = prefs.getInt(PREF_NUM_SAVED_ENTRIES[inde x], 0); |
| 222 try { | 255 try { |
| 223 RecordHistogram.recordTimesHistogram("Android.StrictMode.WebappS haredPrefs", | 256 RecordHistogram.recordTimesHistogram("Android.StrictMode.WebappS haredPrefs", |
| 224 SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECO NDS); | 257 SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECO NDS); |
| 225 } catch (UnsatisfiedLinkError error) { | 258 } catch (UnsatisfiedLinkError error) { |
| 226 // Intentionally ignored - it's ok to miss recording the metric occasionally. | 259 // Intentionally ignored - it's ok to miss recording the metric occasionally. |
| 227 } | 260 } |
| 228 if (numSavedEntries <= NUM_WEBAPP_ACTIVITIES) { | 261 if (numSavedEntries <= NUM_WEBAPP_ACTIVITIES) { |
| 229 for (int i = 0; i < numSavedEntries; ++i) { | 262 for (int i = 0; i < numSavedEntries; ++i) { |
| 230 String currentActivityIndexPref = PREF_ACTIVITY_INDEX + i; | 263 String currentActivityIndexPref = PREF_ACTIVITY_INDEX[index] + i; |
| 231 String currentWebappIdPref = PREF_WEBAPP_ID + i; | 264 String currentWebappIdPref = PREF_WEBAPP_ID[index] + i; |
| 232 | 265 |
| 233 int activityIndex = prefs.getInt(currentActivityIndexPref, i ); | 266 int activityIndex = prefs.getInt(currentActivityIndexPref, i ); |
| 234 String webappId = prefs.getString(currentWebappIdPref, null) ; | 267 String webappId = prefs.getString(currentWebappIdPref, null) ; |
| 235 ActivityEntry entry = new ActivityEntry(activityIndex, webap pId); | 268 ActivityEntry entry = new ActivityEntry(activityIndex, webap pId); |
| 236 | 269 |
| 237 if (availableWebapps.remove(entry.mActivityIndex)) { | 270 if (availableWebapps.remove(entry.mActivityIndex)) { |
| 238 mActivityList.add(entry); | 271 mActivityList[index].add(entry); |
| 239 } else { | 272 } else { |
| 240 // If the same activity was assigned to two different en tries, or if the | 273 // If the same activity was assigned to two different en tries, or if the |
| 241 // number of activities changed, discard it and mark tha t it needs to be | 274 // number of activities changed, discard it and mark tha t it needs to be |
| 242 // rewritten. | 275 // rewritten. |
| 243 isMapDirty = true; | 276 isMapDirty = true; |
| 244 } | 277 } |
| 245 } | 278 } |
| 246 } | 279 } |
| 247 } catch (ClassCastException exception) { | 280 } catch (ClassCastException exception) { |
| 248 // Something went wrong reading the preferences. Nuke everything. | 281 // Something went wrong reading the preferences. Nuke everything. |
| 249 mActivityList.clear(); | 282 mActivityList[index].clear(); |
| 250 availableWebapps.clear(); | 283 availableWebapps.clear(); |
| 251 for (int i = 0; i < NUM_WEBAPP_ACTIVITIES; ++i) { | 284 for (int i = 0; i < NUM_WEBAPP_ACTIVITIES; ++i) { |
| 252 availableWebapps.add(i); | 285 availableWebapps.add(i); |
| 253 } | 286 } |
| 254 } | 287 } |
| 255 | 288 |
| 256 // Add entries for any missing WebappActivities. | 289 // Add entries for any missing WebappActivities/WebApkActivities. |
| 257 for (Integer availableIndex : availableWebapps) { | 290 for (Integer availableIndex : availableWebapps) { |
| 258 ActivityEntry entry = new ActivityEntry(availableIndex, null); | 291 ActivityEntry entry = new ActivityEntry(availableIndex, null); |
| 259 mActivityList.add(entry); | 292 mActivityList[index].add(entry); |
| 260 isMapDirty = true; | 293 isMapDirty = true; |
| 261 } | 294 } |
| 262 | 295 |
| 263 if (isMapDirty) { | 296 if (isMapDirty) { |
| 264 storeActivityList(); | 297 storeActivityList(index); |
| 265 } | 298 } |
| 266 } | 299 } |
| 267 | 300 |
| 268 /** | 301 /** |
| 269 * Saves the mapping between webapps and WebappActivities. | 302 * Saves the mapping between webapps and WebappActivities/WebApkActivities d epending on the |
| 303 * {@link index}. | |
| 270 */ | 304 */ |
| 271 private void storeActivityList() { | 305 private void storeActivityList(int index) { |
| 272 SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE, Co ntext.MODE_PRIVATE); | 306 SharedPreferences prefs = mContext.getSharedPreferences(PREF_PACKAGE[ind ex], |
| 307 Context.MODE_PRIVATE); | |
| 273 SharedPreferences.Editor editor = prefs.edit(); | 308 SharedPreferences.Editor editor = prefs.edit(); |
| 274 editor.clear(); | 309 editor.clear(); |
| 275 editor.putInt(PREF_NUM_SAVED_ENTRIES, mActivityList.size()); | 310 editor.putInt(PREF_NUM_SAVED_ENTRIES[index], mActivityList[index].size() ); |
| 276 for (int i = 0; i < mActivityList.size(); ++i) { | 311 for (int i = 0; i < mActivityList[index].size(); ++i) { |
| 277 String currentActivityIndexPref = PREF_ACTIVITY_INDEX + i; | 312 String currentActivityIndexPref = PREF_ACTIVITY_INDEX[index] + i; |
| 278 String currentWebappIdPref = PREF_WEBAPP_ID + i; | 313 String currentWebappIdPref = PREF_WEBAPP_ID[index] + i; |
| 279 editor.putInt(currentActivityIndexPref, mActivityList.get(i).mActivi tyIndex); | 314 editor.putInt(currentActivityIndexPref, mActivityList[index].get(i). mActivityIndex); |
| 280 editor.putString(currentWebappIdPref, mActivityList.get(i).mWebappId ); | 315 editor.putString(currentWebappIdPref, mActivityList[index].get(i).mW ebappId); |
| 281 } | 316 } |
| 282 editor.apply(); | 317 editor.apply(); |
| 283 } | 318 } |
| 284 } | 319 } |
| OLD | NEW |