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

Side by Side 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: Introduce WebApkActivity. Created 4 years, 6 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 unified diff | Download patch
OLDNEW
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698