OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
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.omaha; | 5 package org.chromium.chrome.browser.omaha; |
6 | 6 |
7 import android.app.AlarmManager; | 7 import android.app.AlarmManager; |
8 import android.app.IntentService; | 8 import android.app.IntentService; |
9 import android.app.PendingIntent; | 9 import android.app.PendingIntent; |
10 import android.content.Context; | 10 import android.content.Context; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 private static final String TAG = "cr.omaha"; | 59 private static final String TAG = "cr.omaha"; |
60 | 60 |
61 // Intent actions. | 61 // Intent actions. |
62 private static final String ACTION_INITIALIZE = | 62 private static final String ACTION_INITIALIZE = |
63 "org.chromium.chrome.browser.omaha.ACTION_INITIALIZE"; | 63 "org.chromium.chrome.browser.omaha.ACTION_INITIALIZE"; |
64 private static final String ACTION_REGISTER_REQUEST = | 64 private static final String ACTION_REGISTER_REQUEST = |
65 "org.chromium.chrome.browser.omaha.ACTION_REGISTER_REQUEST"; | 65 "org.chromium.chrome.browser.omaha.ACTION_REGISTER_REQUEST"; |
66 private static final String ACTION_POST_REQUEST = | 66 private static final String ACTION_POST_REQUEST = |
67 "org.chromium.chrome.browser.omaha.ACTION_POST_REQUEST"; | 67 "org.chromium.chrome.browser.omaha.ACTION_POST_REQUEST"; |
68 | 68 |
69 // Strings for extras. | |
70 private static final String EXTRA_FORCE_ACTION = "forceAction"; | |
71 | |
72 // Delays between events. | 69 // Delays between events. |
73 private static final long MS_PER_HOUR = 3600000; | 70 private static final long MS_PER_HOUR = 3600000; |
74 private static final long MS_POST_BASE_DELAY = MS_PER_HOUR; | 71 private static final long MS_POST_BASE_DELAY = MS_PER_HOUR; |
75 private static final long MS_POST_MAX_DELAY = 5 * MS_PER_HOUR; | 72 private static final long MS_POST_MAX_DELAY = 5 * MS_PER_HOUR; |
76 private static final long MS_BETWEEN_REQUESTS = 5 * MS_PER_HOUR; | 73 private static final long MS_BETWEEN_REQUESTS = 5 * MS_PER_HOUR; |
77 private static final int MS_CONNECTION_TIMEOUT = 60000; | 74 private static final int MS_CONNECTION_TIMEOUT = 60000; |
78 | 75 |
79 // Flags for retrieving the OmahaClient's state after it's written to disk. | 76 // Flags for retrieving the OmahaClient's state after it's written to disk. |
80 // The PREF_PACKAGE doesn't match the current OmahaClient package for histor ical reasons. | 77 // The PREF_PACKAGE doesn't match the current OmahaClient package for histor ical reasons. |
81 @VisibleForTesting | 78 @VisibleForTesting |
(...skipping 29 matching lines...) Expand all Loading... | |
111 | 108 |
112 // Static fields | 109 // Static fields |
113 private static boolean sEnableCommunication = true; | 110 private static boolean sEnableCommunication = true; |
114 private static boolean sEnableUpdateDetection = true; | 111 private static boolean sEnableUpdateDetection = true; |
115 private static VersionNumberGetter sVersionNumberGetter = null; | 112 private static VersionNumberGetter sVersionNumberGetter = null; |
116 private static MarketURLGetter sMarketURLGetter = null; | 113 private static MarketURLGetter sMarketURLGetter = null; |
117 private static Boolean sIsFreshInstallOrDataCleared = null; | 114 private static Boolean sIsFreshInstallOrDataCleared = null; |
118 | 115 |
119 // Member fields not persisted to disk. | 116 // Member fields not persisted to disk. |
120 private boolean mStateHasBeenRestored; | 117 private boolean mStateHasBeenRestored; |
121 private Context mApplicationContext; | |
122 private ExponentialBackoffScheduler mBackoffScheduler; | 118 private ExponentialBackoffScheduler mBackoffScheduler; |
123 private RequestGenerator mGenerator; | 119 private RequestGenerator mGenerator; |
124 | 120 |
125 // State saved written to and read from disk. | 121 // State saved written to and read from disk. |
126 private RequestData mCurrentRequest; | 122 private RequestData mCurrentRequest; |
127 private long mTimestampOfInstall; | 123 private long mTimestampOfInstall; |
128 private long mTimestampForNextPostAttempt; | 124 private long mTimestampForNextPostAttempt; |
129 private long mTimestampForNewRequest; | 125 private long mTimestampForNewRequest; |
130 private String mLatestVersion; | 126 private String mLatestVersion; |
131 private String mMarketURL; | 127 private String mMarketURL; |
132 private String mInstallSource; | 128 private String mInstallSource; |
133 protected boolean mSendInstallEvent; | 129 protected boolean mSendInstallEvent; |
134 | 130 |
135 public OmahaClient() { | 131 public OmahaClient() { |
136 super(TAG); | 132 super(TAG); |
137 setIntentRedelivery(true); | 133 setIntentRedelivery(true); |
138 } | 134 } |
139 | 135 |
140 @Override | |
141 public void onCreate() { | |
142 super.onCreate(); | |
143 mApplicationContext = getApplicationContext(); | |
144 mBackoffScheduler = createBackoffScheduler(PREF_PACKAGE, mApplicationCon text, | |
145 MS_POST_BASE_DELAY, MS_POST_MAX_DELAY); | |
146 mGenerator = createRequestGenerator(mApplicationContext); | |
147 } | |
148 | |
149 /** | 136 /** |
150 * Sets whether Chrome should be communicating with the Omaha server. | 137 * Sets whether Chrome should be communicating with the Omaha server. |
151 * The alternative to using a static field within OmahaClient is using a mem ber variable in | 138 * The alternative to using a static field within OmahaClient is using a mem ber variable in |
152 * the ChromeTabbedActivity. The problem is that it is difficult to set the variable before | 139 * the ChromeTabbedActivity. The problem is that it is difficult to set the variable before |
153 * ChromeTabbedActivity is started. | 140 * ChromeTabbedActivity is started. |
154 */ | 141 */ |
155 @VisibleForTesting | 142 @VisibleForTesting |
156 public static void setEnableCommunication(boolean state) { | 143 public static void setEnableCommunication(boolean state) { |
157 sEnableCommunication = state; | 144 sEnableCommunication = state; |
158 } | 145 } |
(...skipping 11 matching lines...) Expand all Loading... | |
170 return mTimestampForNextPostAttempt; | 157 return mTimestampForNextPostAttempt; |
171 } | 158 } |
172 | 159 |
173 @VisibleForTesting | 160 @VisibleForTesting |
174 long getTimestampForNewRequest() { | 161 long getTimestampForNewRequest() { |
175 return mTimestampForNewRequest; | 162 return mTimestampForNewRequest; |
176 } | 163 } |
177 | 164 |
178 @VisibleForTesting | 165 @VisibleForTesting |
179 int getCumulativeFailedAttempts() { | 166 int getCumulativeFailedAttempts() { |
180 return mBackoffScheduler.getNumFailedAttempts(); | 167 return getBackoffScheduler().getNumFailedAttempts(); |
181 } | 168 } |
182 | 169 |
183 /** | 170 /** |
184 * Creates the scheduler used to space out POST attempts. | 171 * Creates the scheduler used to space out POST attempts. |
185 */ | 172 */ |
186 @VisibleForTesting | 173 @VisibleForTesting |
187 ExponentialBackoffScheduler createBackoffScheduler(String prefPackage, Conte xt context, | 174 ExponentialBackoffScheduler createBackoffScheduler(String prefPackage, Conte xt context, |
188 long base, long max) { | 175 long base, long max) { |
189 return new ExponentialBackoffScheduler(prefPackage, context, base, max); | 176 return new ExponentialBackoffScheduler(prefPackage, context, base, max); |
190 } | 177 } |
191 | 178 |
192 /** | 179 /** |
193 * Creates the request generator used to create Omaha XML. | 180 * Creates the request generator used to create Omaha XML. |
194 */ | 181 */ |
195 @VisibleForTesting | 182 @VisibleForTesting |
196 RequestGenerator createRequestGenerator(Context context) { | 183 RequestGenerator createRequestGenerator(Context context) { |
197 return ((ChromeApplication) getApplicationContext()).createOmahaRequestG enerator(); | 184 return ((ChromeApplication) context.getApplicationContext()).createOmaha RequestGenerator(); |
198 } | 185 } |
199 | 186 |
200 /** | 187 /** |
201 * Handles an action on a thread separate from the UI thread. | 188 * Handles an action on a thread separate from the UI thread. |
202 * @param intent Intent fired by some part of Chrome. | 189 * @param intent Intent fired by some part of Chrome. |
203 */ | 190 */ |
204 @Override | 191 @Override |
205 public void onHandleIntent(Intent intent) { | 192 public void onHandleIntent(Intent intent) { |
206 assert Looper.myLooper() != Looper.getMainLooper(); | 193 assert Looper.myLooper() != Looper.getMainLooper(); |
207 | 194 |
208 if (!sEnableCommunication) { | 195 if (!sEnableCommunication) { |
209 Log.v(TAG, "Disabled. Ignoring intent."); | 196 Log.v(TAG, "Disabled. Ignoring intent."); |
210 return; | 197 return; |
211 } | 198 } |
212 | 199 |
213 if (mGenerator == null) { | |
214 Log.e(TAG, "No request generator set. Ignoring intent."); | |
215 return; | |
216 } | |
217 | |
218 if (!mStateHasBeenRestored) { | 200 if (!mStateHasBeenRestored) { |
219 restoreState(); | 201 restoreState(); |
220 } | 202 } |
221 | 203 |
222 if (ACTION_INITIALIZE.equals(intent.getAction())) { | 204 if (ACTION_INITIALIZE.equals(intent.getAction())) { |
223 handleInitialize(); | 205 handleInitialize(); |
224 } else if (ACTION_REGISTER_REQUEST.equals(intent.getAction())) { | 206 } else if (ACTION_REGISTER_REQUEST.equals(intent.getAction())) { |
225 handleRegisterRequest(intent); | 207 handleRegisterRequest(intent); |
226 } else if (ACTION_POST_REQUEST.equals(intent.getAction())) { | 208 } else if (ACTION_POST_REQUEST.equals(intent.getAction())) { |
227 handlePostRequestIntent(intent); | 209 handlePostRequestIntent(intent); |
228 } else { | 210 } else { |
229 Log.e(TAG, "Got unknown action from intent: " + intent.getAction()); | 211 Log.e(TAG, "Got unknown action from intent: " + intent.getAction()); |
230 } | 212 } |
231 } | 213 } |
232 | 214 |
233 public static Intent createInitializeIntent(Context context) { | 215 public static Intent createInitializeIntent(Context context) { |
234 Intent intent = new Intent(context, OmahaClient.class); | 216 Intent intent = new Intent(context, OmahaClient.class); |
235 intent.setAction(ACTION_INITIALIZE); | 217 intent.setAction(ACTION_INITIALIZE); |
236 return intent; | 218 return intent; |
237 } | 219 } |
238 | 220 |
239 /** | 221 /** |
240 * Start a recurring alarm to fire request generation intents. | 222 * Start a recurring alarm to fire request generation intents. |
241 */ | 223 */ |
242 private void handleInitialize() { | 224 private void handleInitialize() { |
243 scheduleRepeatingAlarm(); | 225 scheduleRepeatingAlarm(); |
244 | 226 |
245 // If a request exists, fire a POST intent to restart its timer. | 227 // If a request exists, fire a POST intent to restart its timer. |
246 if (hasRequest()) { | 228 if (hasRequest()) startService(createPostRequestIntent(this)); |
247 Intent postIntent = createPostRequestIntent(mApplicationContext, fal se); | |
248 startService(postIntent); | |
249 } | |
250 } | 229 } |
251 | 230 |
252 public static Intent createRegisterRequestIntent(Context context, boolean fo rce) { | 231 /** |
232 * Returns an Intent for registering a new request to send to the server. | |
233 */ | |
234 static Intent createRegisterRequestIntent(Context context) { | |
253 Intent intent = new Intent(context, OmahaClient.class); | 235 Intent intent = new Intent(context, OmahaClient.class); |
254 intent.setAction(ACTION_REGISTER_REQUEST); | 236 intent.setAction(ACTION_REGISTER_REQUEST); |
255 intent.putExtra(EXTRA_FORCE_ACTION, force); | |
256 return intent; | 237 return intent; |
257 } | 238 } |
258 | 239 |
259 /** | 240 /** |
260 * Determines if a new request should be generated. New requests are only g enerated if enough | 241 * Determines if a new request should be generated. New requests are only g enerated if enough |
261 * time has passed between now and the last time a request was generated. | 242 * time has passed between now and the last time a request was generated. |
262 */ | 243 */ |
263 private void handleRegisterRequest(Intent intent) { | 244 private void handleRegisterRequest(Intent intent) { |
264 boolean force = intent.getBooleanExtra(EXTRA_FORCE_ACTION, false); | 245 if (!isChromeBeingUsed()) { |
265 if (!isChromeBeingUsed() && !force) { | |
266 cancelRepeatingAlarm(); | 246 cancelRepeatingAlarm(); |
267 return; | 247 return; |
268 } | 248 } |
269 | 249 |
270 // If the current request is too old, generate a new one. | 250 // If the current request is too old, generate a new one. |
271 long currentTimestamp = mBackoffScheduler.getCurrentTime(); | 251 long currentTimestamp = getBackoffScheduler().getCurrentTime(); |
272 boolean isTooOld = hasRequest() | 252 boolean isTooOld = hasRequest() |
273 && mCurrentRequest.getAgeInMilliseconds(currentTimestamp) >= MS_ BETWEEN_REQUESTS; | 253 && mCurrentRequest.getAgeInMilliseconds(currentTimestamp) >= MS_ BETWEEN_REQUESTS; |
274 boolean isOverdue = !hasRequest() && currentTimestamp >= mTimestampForNe wRequest; | 254 boolean isOverdue = !hasRequest() && currentTimestamp >= mTimestampForNe wRequest; |
275 if (isTooOld || isOverdue || force) { | 255 if (isTooOld || isOverdue) { |
276 registerNewRequest(currentTimestamp); | 256 registerNewRequest(currentTimestamp); |
277 } | 257 } |
278 | 258 |
279 // Create an intent to send the request. If we're forcing a registratio n, force the POST, | 259 // Create an intent to send the request. |
280 // as well. | |
281 if (hasRequest()) { | 260 if (hasRequest()) { |
282 Intent postIntent = createPostRequestIntent(mApplicationContext, for ce); | 261 startService(createPostRequestIntent(this)); |
283 startService(postIntent); | |
284 } | 262 } |
285 } | 263 } |
286 | 264 |
287 public static Intent createPostRequestIntent(Context context, boolean force) { | 265 /** |
266 * Returns an Intent for POSTing the current request to the Omaha server. | |
267 */ | |
268 static Intent createPostRequestIntent(Context context) { | |
288 Intent intent = new Intent(context, OmahaClient.class); | 269 Intent intent = new Intent(context, OmahaClient.class); |
289 intent.setAction(ACTION_POST_REQUEST); | 270 intent.setAction(ACTION_POST_REQUEST); |
290 intent.putExtra(EXTRA_FORCE_ACTION, force); | |
291 return intent; | 271 return intent; |
292 } | 272 } |
293 | 273 |
294 /** | 274 /** |
295 * Sends the request it is holding. | 275 * Sends the request it is holding. |
296 */ | 276 */ |
297 @VisibleForTesting | 277 @VisibleForTesting |
298 private void handlePostRequestIntent(Intent intent) { | 278 private void handlePostRequestIntent(Intent intent) { |
299 if (!hasRequest()) { | 279 if (!hasRequest()) { |
300 return; | 280 return; |
301 } | 281 } |
302 | 282 |
303 boolean force = intent.getBooleanExtra(EXTRA_FORCE_ACTION, false); | |
304 | |
305 // If enough time has passed since the last attempt, try sending a reque st. | 283 // If enough time has passed since the last attempt, try sending a reque st. |
306 long currentTimestamp = mBackoffScheduler.getCurrentTime(); | 284 long currentTimestamp = getBackoffScheduler().getCurrentTime(); |
307 if (currentTimestamp >= mTimestampForNextPostAttempt || force) { | 285 if (currentTimestamp >= mTimestampForNextPostAttempt) { |
308 // All requests made during the same session should have the same ID . | 286 // All requests made during the same session should have the same ID . |
309 String sessionID = generateRandomUUID(); | 287 String sessionID = generateRandomUUID(); |
310 boolean sendingInstallRequest = mSendInstallEvent; | 288 boolean sendingInstallRequest = mSendInstallEvent; |
311 boolean succeeded = generateAndPostRequest(currentTimestamp, session ID); | 289 boolean succeeded = generateAndPostRequest(currentTimestamp, session ID); |
312 | 290 |
313 if (succeeded && sendingInstallRequest) { | 291 if (succeeded && sendingInstallRequest) { |
314 // Only the first request ever generated should contain an insta ll event. | 292 // Only the first request ever generated should contain an insta ll event. |
315 mSendInstallEvent = false; | 293 mSendInstallEvent = false; |
316 | 294 |
317 // Create and immediately send another request for a ping and up date check. | 295 // Create and immediately send another request for a ping and up date check. |
318 registerNewRequest(currentTimestamp); | 296 registerNewRequest(currentTimestamp); |
319 succeeded = generateAndPostRequest(currentTimestamp, sessionID); | 297 generateAndPostRequest(currentTimestamp, sessionID); |
nyquist
2015/09/01 22:32:50
So this ignores the return value of the function n
gone
2015/09/01 22:36:12
There's a call right above this where the boolean
| |
320 } | |
321 | |
322 if (force) { | |
323 if (succeeded) { | |
324 Log.v(TAG, "Requests successfully sent to Omaha server."); | |
325 } else { | |
326 Log.e(TAG, "Requests failed to reach Omaha server."); | |
327 } | |
328 } | 298 } |
329 } else { | 299 } else { |
330 // Set an alarm to POST at the proper time. Previous alarms are des troyed. | 300 // Set an alarm to POST at the proper time. Previous alarms are des troyed. |
331 Intent postIntent = createPostRequestIntent(mApplicationContext, fal se); | 301 Intent postIntent = createPostRequestIntent(this); |
332 mBackoffScheduler.createAlarm(postIntent, mTimestampForNextPostAttem pt); | 302 getBackoffScheduler().createAlarm(postIntent, mTimestampForNextPostA ttempt); |
333 } | 303 } |
334 | 304 |
335 // Write everything back out again to save our state. | 305 // Write everything back out again to save our state. |
336 saveState(); | 306 saveState(); |
337 } | 307 } |
338 | 308 |
339 private boolean generateAndPostRequest(long currentTimestamp, String session ID) { | 309 private boolean generateAndPostRequest(long currentTimestamp, String session ID) { |
310 ExponentialBackoffScheduler scheduler = getBackoffScheduler(); | |
340 try { | 311 try { |
341 // Generate the XML for the current request. | 312 // Generate the XML for the current request. |
342 long installAgeInDays = RequestGenerator.installAge(currentTimestamp , | 313 long installAgeInDays = RequestGenerator.installAge(currentTimestamp , |
343 mTimestampOfInstall, mCurrentRequest.isSendInstallEvent()); | 314 mTimestampOfInstall, mCurrentRequest.isSendInstallEvent()); |
344 String version = getVersionNumberGetter().getCurrentlyUsedVersion(mA pplicationContext); | 315 String version = getVersionNumberGetter().getCurrentlyUsedVersion(th is); |
345 String xml = | 316 String xml = getRequestGenerator().generateXML( |
346 mGenerator.generateXML(sessionID, version, installAgeInDays, mCurrentRequest); | 317 sessionID, version, installAgeInDays, mCurrentRequest); |
347 | 318 |
348 // Send the request to the server & wait for a response. | 319 // Send the request to the server & wait for a response. |
349 String response = postRequest(currentTimestamp, xml); | 320 String response = postRequest(currentTimestamp, xml); |
350 parseServerResponse(response); | 321 parseServerResponse(response); |
351 | 322 |
352 // If we've gotten this far, we've successfully sent a request. | 323 // If we've gotten this far, we've successfully sent a request. |
353 mCurrentRequest = null; | 324 mCurrentRequest = null; |
354 mTimestampForNextPostAttempt = currentTimestamp + MS_POST_BASE_DELAY ; | 325 mTimestampForNextPostAttempt = currentTimestamp + MS_POST_BASE_DELAY ; |
355 mBackoffScheduler.resetFailedAttempts(); | 326 scheduler.resetFailedAttempts(); |
356 Log.i(TAG, "Request to Server Successful. Timestamp for next request :" | 327 Log.i(TAG, "Request to Server Successful. Timestamp for next request :" |
357 + String.valueOf(mTimestampForNextPostAttempt)); | 328 + String.valueOf(mTimestampForNextPostAttempt)); |
358 | 329 |
359 return true; | 330 return true; |
360 } catch (RequestFailureException e) { | 331 } catch (RequestFailureException e) { |
361 // Set the alarm to try again later. | 332 // Set the alarm to try again later. |
362 Log.e(TAG, "Failed to contact server: ", e); | 333 Log.e(TAG, "Failed to contact server: ", e); |
363 Intent postIntent = createPostRequestIntent(mApplicationContext, fal se); | 334 Intent postIntent = createPostRequestIntent(this); |
364 mTimestampForNextPostAttempt = mBackoffScheduler.createAlarm(postInt ent); | 335 mTimestampForNextPostAttempt = scheduler.createAlarm(postIntent); |
365 mBackoffScheduler.increaseFailedAttempts(); | 336 scheduler.increaseFailedAttempts(); |
366 return false; | 337 return false; |
367 } | 338 } |
368 } | 339 } |
369 | 340 |
370 /** | 341 /** |
371 * Sets a repeating alarm that fires request registration Intents. | 342 * Sets a repeating alarm that fires request registration Intents. |
372 * Setting the alarm overwrites whatever alarm is already there, and rebooti ng | 343 * Setting the alarm overwrites whatever alarm is already there, and rebooti ng |
373 * clears whatever alarms are currently set. | 344 * clears whatever alarms are currently set. |
374 */ | 345 */ |
375 private void scheduleRepeatingAlarm() { | 346 private void scheduleRepeatingAlarm() { |
376 Intent registerIntent = createRegisterRequestIntent(mApplicationContext, false); | 347 Intent registerIntent = createRegisterRequestIntent(this); |
377 PendingIntent pIntent = | 348 PendingIntent pIntent = PendingIntent.getService(this, 0, registerIntent , 0); |
378 PendingIntent.getService(mApplicationContext, 0, registerIntent, 0); | 349 AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE) ; |
379 AlarmManager am = | |
380 (AlarmManager) mApplicationContext.getSystemService(Context.ALAR M_SERVICE); | |
381 setAlarm(am, pIntent, AlarmManager.RTC, mTimestampForNewRequest); | 350 setAlarm(am, pIntent, AlarmManager.RTC, mTimestampForNewRequest); |
382 } | 351 } |
383 | 352 |
384 /** | 353 /** |
385 * Sets up a timer to fire after each interval. | 354 * Sets up a timer to fire after each interval. |
386 * Override to prevent a real alarm from being set. | 355 * Override to prevent a real alarm from being set. |
387 */ | 356 */ |
388 @VisibleForTesting | 357 @VisibleForTesting |
389 protected void setAlarm(AlarmManager am, PendingIntent operation, int alarmT ype, | 358 protected void setAlarm(AlarmManager am, PendingIntent operation, int alarmT ype, |
390 long triggerAtTime) { | 359 long triggerAtTime) { |
391 try { | 360 try { |
392 am.setRepeating(AlarmManager.RTC, triggerAtTime, MS_BETWEEN_REQUESTS , operation); | 361 am.setRepeating(AlarmManager.RTC, triggerAtTime, MS_BETWEEN_REQUESTS , operation); |
393 } catch (SecurityException e) { | 362 } catch (SecurityException e) { |
394 Log.e(TAG, "Failed to set repeating alarm."); | 363 Log.e(TAG, "Failed to set repeating alarm."); |
395 } | 364 } |
396 } | 365 } |
397 | 366 |
398 /** | 367 /** |
399 * Cancels the alarm that launches this service. It will be replaced when C hrome next resumes. | 368 * Cancels the alarm that launches this service. It will be replaced when C hrome next resumes. |
400 */ | 369 */ |
401 private void cancelRepeatingAlarm() { | 370 private void cancelRepeatingAlarm() { |
402 Intent requestIntent = createRegisterRequestIntent(mApplicationContext, false); | 371 Intent requestIntent = createRegisterRequestIntent(this); |
403 PendingIntent pendingIntent = PendingIntent.getService(mApplicationConte xt, 0, | 372 PendingIntent pendingIntent = |
404 requestIntent, PendingIntent.FLAG_NO_CREATE); | 373 PendingIntent.getService(this, 0, requestIntent, PendingIntent.F LAG_NO_CREATE); |
405 // Setting FLAG_NO_CREATE forces Android to return an already existing P endingIntent. | 374 // Setting FLAG_NO_CREATE forces Android to return an already existing P endingIntent. |
406 // Here it would be the one that was used to create the existing alarm ( if it exists). | 375 // Here it would be the one that was used to create the existing alarm ( if it exists). |
407 // If the pendingIntent is null, it is likely that no alarm was created. | 376 // If the pendingIntent is null, it is likely that no alarm was created. |
408 if (pendingIntent != null) { | 377 if (pendingIntent != null) { |
409 AlarmManager am = | 378 AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERV ICE); |
410 (AlarmManager) mApplicationContext.getSystemService(Context. ALARM_SERVICE); | |
411 am.cancel(pendingIntent); | 379 am.cancel(pendingIntent); |
412 pendingIntent.cancel(); | 380 pendingIntent.cancel(); |
413 } | 381 } |
414 } | 382 } |
415 | 383 |
416 /** | 384 /** |
417 * Determine whether or not Chrome is currently being used actively. | 385 * Determine whether or not Chrome is currently being used actively. |
418 */ | 386 */ |
419 @VisibleForTesting | 387 @VisibleForTesting |
420 protected boolean isChromeBeingUsed() { | 388 protected boolean isChromeBeingUsed() { |
421 boolean isChromeVisible = ApplicationStatus.hasVisibleActivities(); | 389 boolean isChromeVisible = ApplicationStatus.hasVisibleActivities(); |
422 boolean isScreenOn = ApiCompatibilityUtils.isInteractive(mApplicationCon text); | 390 boolean isScreenOn = ApiCompatibilityUtils.isInteractive(this); |
423 return isChromeVisible && isScreenOn; | 391 return isChromeVisible && isScreenOn; |
424 } | 392 } |
425 | 393 |
426 /** | 394 /** |
427 * Registers a new request with the current timestamp. Internal timestamps are reset to start | 395 * Registers a new request with the current timestamp. Internal timestamps are reset to start |
428 * fresh. | 396 * fresh. |
429 * @param currentTimestamp Current time. | 397 * @param currentTimestamp Current time. |
430 */ | 398 */ |
431 @VisibleForTesting | 399 @VisibleForTesting |
432 void registerNewRequest(long currentTimestamp) { | 400 void registerNewRequest(long currentTimestamp) { |
433 mCurrentRequest = createRequestData(currentTimestamp, null); | 401 mCurrentRequest = createRequestData(currentTimestamp, null); |
434 mBackoffScheduler.resetFailedAttempts(); | 402 getBackoffScheduler().resetFailedAttempts(); |
435 mTimestampForNextPostAttempt = currentTimestamp; | 403 mTimestampForNextPostAttempt = currentTimestamp; |
436 | 404 |
437 // Tentatively set the timestamp for a new request. This will be update d when the server | 405 // Tentatively set the timestamp for a new request. This will be update d when the server |
438 // is successfully contacted. | 406 // is successfully contacted. |
439 mTimestampForNewRequest = currentTimestamp + MS_BETWEEN_REQUESTS; | 407 mTimestampForNewRequest = currentTimestamp + MS_BETWEEN_REQUESTS; |
440 scheduleRepeatingAlarm(); | 408 scheduleRepeatingAlarm(); |
441 | 409 |
442 saveState(); | 410 saveState(); |
443 } | 411 } |
444 | 412 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 } | 447 } |
480 } | 448 } |
481 | 449 |
482 return response; | 450 return response; |
483 } | 451 } |
484 | 452 |
485 /** | 453 /** |
486 * Parse the server's response and confirm that we received an OK response. | 454 * Parse the server's response and confirm that we received an OK response. |
487 */ | 455 */ |
488 private void parseServerResponse(String response) throws RequestFailureExcep tion { | 456 private void parseServerResponse(String response) throws RequestFailureExcep tion { |
489 String appId = mGenerator.getAppId(); | 457 String appId = getRequestGenerator().getAppId(); |
490 boolean sentPingAndUpdate = !mSendInstallEvent; | 458 boolean sentPingAndUpdate = !mSendInstallEvent; |
491 ResponseParser parser = | 459 ResponseParser parser = |
492 new ResponseParser(appId, mSendInstallEvent, sentPingAndUpdate, sentPingAndUpdate); | 460 new ResponseParser(appId, mSendInstallEvent, sentPingAndUpdate, sentPingAndUpdate); |
493 parser.parseResponse(response); | 461 parser.parseResponse(response); |
494 mTimestampForNewRequest = mBackoffScheduler.getCurrentTime() + MS_BETWEE N_REQUESTS; | 462 mTimestampForNewRequest = getBackoffScheduler().getCurrentTime() + MS_BE TWEEN_REQUESTS; |
495 mLatestVersion = parser.getNewVersion(); | 463 mLatestVersion = parser.getNewVersion(); |
496 mMarketURL = parser.getURL(); | 464 mMarketURL = parser.getURL(); |
497 scheduleRepeatingAlarm(); | 465 scheduleRepeatingAlarm(); |
498 } | 466 } |
499 | 467 |
500 /** | 468 /** |
501 * Returns a HttpURLConnection to the server. | 469 * Returns a HttpURLConnection to the server. |
502 */ | 470 */ |
503 @VisibleForTesting | 471 @VisibleForTesting |
504 protected HttpURLConnection createConnection() throws RequestFailureExceptio n { | 472 protected HttpURLConnection createConnection() throws RequestFailureExceptio n { |
505 try { | 473 try { |
506 URL url = new URL(mGenerator.getServerUrl()); | 474 URL url = new URL(getRequestGenerator().getServerUrl()); |
507 HttpURLConnection connection = (HttpURLConnection) url.openConnectio n(); | 475 HttpURLConnection connection = (HttpURLConnection) url.openConnectio n(); |
508 connection.setConnectTimeout(MS_CONNECTION_TIMEOUT); | 476 connection.setConnectTimeout(MS_CONNECTION_TIMEOUT); |
509 connection.setReadTimeout(MS_CONNECTION_TIMEOUT); | 477 connection.setReadTimeout(MS_CONNECTION_TIMEOUT); |
510 return connection; | 478 return connection; |
511 } catch (MalformedURLException e) { | 479 } catch (MalformedURLException e) { |
512 throw new RequestFailureException("Caught a malformed URL exception. ", e); | 480 throw new RequestFailureException("Caught a malformed URL exception. ", e); |
513 } catch (IOException e) { | 481 } catch (IOException e) { |
514 throw new RequestFailureException("Failed to open connection to URL" , e); | 482 throw new RequestFailureException("Failed to open connection to URL" , e); |
515 } | 483 } |
516 } | 484 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 } | 559 } |
592 } | 560 } |
593 | 561 |
594 /** | 562 /** |
595 * Checks if we know about a newer version available than the one we're usin g. This does not | 563 * Checks if we know about a newer version available than the one we're usin g. This does not |
596 * actually fire any requests over to the server; it just checks the version we stored the last | 564 * actually fire any requests over to the server; it just checks the version we stored the last |
597 * time we talked to the Omaha server. | 565 * time we talked to the Omaha server. |
598 * | 566 * |
599 * NOTE: This function incurs I/O, so don't use it on the main thread. | 567 * NOTE: This function incurs I/O, so don't use it on the main thread. |
600 */ | 568 */ |
601 public static boolean isNewerVersionAvailable(Context applicationContext) { | 569 static boolean isNewerVersionAvailable(Context context) { |
602 assert Looper.myLooper() != Looper.getMainLooper(); | 570 assert Looper.myLooper() != Looper.getMainLooper(); |
603 | 571 |
604 // This may be explicitly enabled for some channels and for unit tests. | 572 // This may be explicitly enabled for some channels and for unit tests. |
605 if (!sEnableUpdateDetection) { | 573 if (!sEnableUpdateDetection) { |
606 return false; | 574 return false; |
607 } | 575 } |
608 | 576 |
609 // If the market link is bad, don't show an update to avoid frustrating users trying to | 577 // If the market link is bad, don't show an update to avoid frustrating users trying to |
610 // hit the "Update" button. | 578 // hit the "Update" button. |
611 if ("".equals(getMarketURL(applicationContext))) { | 579 if ("".equals(getMarketURL(context))) { |
612 return false; | 580 return false; |
613 } | 581 } |
614 | 582 |
615 // Compare version numbers. | 583 // Compare version numbers. |
616 VersionNumberGetter getter = getVersionNumberGetter(); | 584 VersionNumberGetter getter = getVersionNumberGetter(); |
617 String currentStr = getter.getCurrentlyUsedVersion(applicationContext); | 585 String currentStr = getter.getCurrentlyUsedVersion(context); |
618 String latestStr = | 586 String latestStr = getter.getLatestKnownVersion(context, PREF_PACKAGE, P REF_LATEST_VERSION); |
619 getter.getLatestKnownVersion(applicationContext, PREF_PACKAGE, P REF_LATEST_VERSION); | |
620 | 587 |
621 VersionNumber currentVersionNumber = VersionNumber.fromString(currentStr ); | 588 VersionNumber currentVersionNumber = VersionNumber.fromString(currentStr ); |
622 VersionNumber latestVersionNumber = VersionNumber.fromString(latestStr); | 589 VersionNumber latestVersionNumber = VersionNumber.fromString(latestStr); |
623 | 590 |
624 if (currentVersionNumber == null || latestVersionNumber == null) { | 591 if (currentVersionNumber == null || latestVersionNumber == null) { |
625 return false; | 592 return false; |
626 } | 593 } |
627 | 594 |
628 return currentVersionNumber.isSmallerThan(latestVersionNumber); | 595 return currentVersionNumber.isSmallerThan(latestVersionNumber); |
629 } | 596 } |
630 | 597 |
631 /** | 598 /** |
632 * Determine how the Chrome APK arrived on the device. | 599 * Determine how the Chrome APK arrived on the device. |
633 * @param context Context to pull resources from. | 600 * @param context Context to pull resources from. |
634 * @return A String indicating the install source. | 601 * @return A String indicating the install source. |
635 */ | 602 */ |
636 String determineInstallSource(Context context) { | 603 String determineInstallSource() { |
637 boolean isInSystemImage = (getApplicationFlags() & ApplicationInfo.FLAG_ SYSTEM) != 0; | 604 boolean isInSystemImage = (getApplicationFlags() & ApplicationInfo.FLAG_ SYSTEM) != 0; |
638 return isInSystemImage ? INSTALL_SOURCE_SYSTEM : INSTALL_SOURCE_ORGANIC; | 605 return isInSystemImage ? INSTALL_SOURCE_SYSTEM : INSTALL_SOURCE_ORGANIC; |
639 } | 606 } |
640 | 607 |
641 /** | 608 /** |
642 * Returns the Application's flags, used to determine if Chrome was installe d as part of the | 609 * Returns the Application's flags, used to determine if Chrome was installe d as part of the |
643 * system image. | 610 * system image. |
644 * @return The Application's flags. | 611 * @return The Application's flags. |
645 */ | 612 */ |
646 @VisibleForTesting | 613 @VisibleForTesting |
647 public int getApplicationFlags() { | 614 int getApplicationFlags() { |
648 return mApplicationContext.getApplicationInfo().flags; | 615 return getApplicationInfo().flags; |
649 } | 616 } |
650 | 617 |
651 /** | 618 /** |
652 * Reads the data back from the file it was saved to. Uses SharedPreference s to handle I/O. | 619 * Reads the data back from the file it was saved to. Uses SharedPreference s to handle I/O. |
653 * Sanity checks are performed on the timestamps to guard against clock chan ging. | 620 * Sanity checks are performed on the timestamps to guard against clock chan ging. |
654 */ | 621 */ |
655 @VisibleForTesting | 622 @VisibleForTesting |
656 void restoreState() { | 623 void restoreState() { |
657 boolean mustRewriteState = false; | 624 boolean mustRewriteState = false; |
658 SharedPreferences preferences = | 625 SharedPreferences preferences = getSharedPreferences(PREF_PACKAGE, Conte xt.MODE_PRIVATE); |
659 mApplicationContext.getSharedPreferences(PREF_PACKAGE, Context.M ODE_PRIVATE); | |
660 Map<String, ?> items = preferences.getAll(); | 626 Map<String, ?> items = preferences.getAll(); |
661 | 627 |
662 // Read out the recorded data. | 628 // Read out the recorded data. |
663 long currentTime = mBackoffScheduler.getCurrentTime(); | 629 long currentTime = getBackoffScheduler().getCurrentTime(); |
664 mTimestampForNewRequest = | 630 mTimestampForNewRequest = |
665 getLongFromMap(items, PREF_TIMESTAMP_FOR_NEW_REQUEST, currentTim e); | 631 getLongFromMap(items, PREF_TIMESTAMP_FOR_NEW_REQUEST, currentTim e); |
666 mTimestampForNextPostAttempt = | 632 mTimestampForNextPostAttempt = |
667 getLongFromMap(items, PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, curr entTime); | 633 getLongFromMap(items, PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, curr entTime); |
668 | 634 |
669 long requestTimestamp = getLongFromMap(items, PREF_TIMESTAMP_OF_REQUEST, INVALID_TIMESTAMP); | 635 long requestTimestamp = getLongFromMap(items, PREF_TIMESTAMP_OF_REQUEST, INVALID_TIMESTAMP); |
670 | 636 |
671 // If the preference doesn't exist, it's likely that we haven't sent an install event. | 637 // If the preference doesn't exist, it's likely that we haven't sent an install event. |
672 mSendInstallEvent = getBooleanFromMap(items, PREF_SEND_INSTALL_EVENT, tr ue); | 638 mSendInstallEvent = getBooleanFromMap(items, PREF_SEND_INSTALL_EVENT, tr ue); |
673 | 639 |
674 // Restore the install source. | 640 // Restore the install source. |
675 String defaultInstallSource = determineInstallSource(mApplicationContext ); | 641 String defaultInstallSource = determineInstallSource(); |
676 mInstallSource = getStringFromMap(items, PREF_INSTALL_SOURCE, defaultIns tallSource); | 642 mInstallSource = getStringFromMap(items, PREF_INSTALL_SOURCE, defaultIns tallSource); |
677 | 643 |
678 // If we're not sending an install event, don't bother restoring the req uest ID: | 644 // If we're not sending an install event, don't bother restoring the req uest ID: |
679 // the server does not expect to have persisted request IDs for pings or update checks. | 645 // the server does not expect to have persisted request IDs for pings or update checks. |
680 String persistedRequestId = mSendInstallEvent | 646 String persistedRequestId = mSendInstallEvent |
681 ? getStringFromMap(items, PREF_PERSISTED_REQUEST_ID, INVALID_REQ UEST_ID) | 647 ? getStringFromMap(items, PREF_PERSISTED_REQUEST_ID, INVALID_REQ UEST_ID) |
682 : INVALID_REQUEST_ID; | 648 : INVALID_REQUEST_ID; |
683 | 649 |
684 mCurrentRequest = requestTimestamp == INVALID_TIMESTAMP | 650 mCurrentRequest = requestTimestamp == INVALID_TIMESTAMP |
685 ? null : createRequestData(requestTimestamp, persistedRequestId) ; | 651 ? null : createRequestData(requestTimestamp, persistedRequestId) ; |
686 | 652 |
687 mLatestVersion = getStringFromMap(items, PREF_LATEST_VERSION, ""); | 653 mLatestVersion = getStringFromMap(items, PREF_LATEST_VERSION, ""); |
688 mMarketURL = getStringFromMap(items, PREF_MARKET_URL, ""); | 654 mMarketURL = getStringFromMap(items, PREF_MARKET_URL, ""); |
689 | 655 |
690 // If we don't have a timestamp for when we installed Chrome, then set i t to now. | 656 // If we don't have a timestamp for when we installed Chrome, then set i t to now. |
691 mTimestampOfInstall = getLongFromMap(items, PREF_TIMESTAMP_OF_INSTALL, c urrentTime); | 657 mTimestampOfInstall = getLongFromMap(items, PREF_TIMESTAMP_OF_INSTALL, c urrentTime); |
692 | 658 |
693 // Confirm that the timestamp for the next request is less than the base delay. | 659 // Confirm that the timestamp for the next request is less than the base delay. |
694 long delayToNewRequest = mTimestampForNewRequest - currentTime; | 660 long delayToNewRequest = mTimestampForNewRequest - currentTime; |
695 if (delayToNewRequest > MS_BETWEEN_REQUESTS) { | 661 if (delayToNewRequest > MS_BETWEEN_REQUESTS) { |
696 Log.w(TAG, "Delay to next request (" + delayToNewRequest | 662 Log.w(TAG, "Delay to next request (" + delayToNewRequest |
697 + ") is longer than expected. Resetting to now."); | 663 + ") is longer than expected. Resetting to now."); |
698 mTimestampForNewRequest = currentTime; | 664 mTimestampForNewRequest = currentTime; |
699 mustRewriteState = true; | 665 mustRewriteState = true; |
700 } | 666 } |
701 | 667 |
702 // Confirm that the timestamp for the next POST is less than the current delay. | 668 // Confirm that the timestamp for the next POST is less than the current delay. |
703 long delayToNextPost = mTimestampForNextPostAttempt - currentTime; | 669 long delayToNextPost = mTimestampForNextPostAttempt - currentTime; |
704 if (delayToNextPost > mBackoffScheduler.getGeneratedDelay()) { | 670 if (delayToNextPost > getBackoffScheduler().getGeneratedDelay()) { |
705 Log.w(TAG, "Delay to next post attempt (" + delayToNextPost | 671 Log.w(TAG, "Delay to next post attempt (" + delayToNextPost |
706 + ") is greater than expected (" + mBackoffScheduler.getGene ratedDelay() | 672 + ") is greater than expected (" + getBackoffScheduler().get GeneratedDelay() |
707 + "). Resetting to now."); | 673 + "). Resetting to now."); |
708 mTimestampForNextPostAttempt = currentTime; | 674 mTimestampForNextPostAttempt = currentTime; |
709 mustRewriteState = true; | 675 mustRewriteState = true; |
710 } | 676 } |
711 | 677 |
712 if (mustRewriteState) { | 678 if (mustRewriteState) { |
713 saveState(); | 679 saveState(); |
714 } | 680 } |
715 | 681 |
716 mStateHasBeenRestored = true; | 682 mStateHasBeenRestored = true; |
717 } | 683 } |
718 | 684 |
719 /** | 685 /** |
720 * Writes out the current state to a file. | 686 * Writes out the current state to a file. |
721 */ | 687 */ |
722 private void saveState() { | 688 private void saveState() { |
723 SharedPreferences prefs = | 689 SharedPreferences prefs = getSharedPreferences(PREF_PACKAGE, Context.MOD E_PRIVATE); |
724 mApplicationContext.getSharedPreferences(PREF_PACKAGE, Context.M ODE_PRIVATE); | |
725 SharedPreferences.Editor editor = prefs.edit(); | 690 SharedPreferences.Editor editor = prefs.edit(); |
726 editor.putBoolean(PREF_SEND_INSTALL_EVENT, mSendInstallEvent); | 691 editor.putBoolean(PREF_SEND_INSTALL_EVENT, mSendInstallEvent); |
727 setIsFreshInstallOrDataHasBeenCleared(mApplicationContext); | 692 setIsFreshInstallOrDataHasBeenCleared(this); |
728 editor.putLong(PREF_TIMESTAMP_OF_INSTALL, mTimestampOfInstall); | 693 editor.putLong(PREF_TIMESTAMP_OF_INSTALL, mTimestampOfInstall); |
729 editor.putLong(PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, mTimestampForNextPo stAttempt); | 694 editor.putLong(PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, mTimestampForNextPo stAttempt); |
730 editor.putLong(PREF_TIMESTAMP_FOR_NEW_REQUEST, mTimestampForNewRequest); | 695 editor.putLong(PREF_TIMESTAMP_FOR_NEW_REQUEST, mTimestampForNewRequest); |
731 editor.putLong(PREF_TIMESTAMP_OF_REQUEST, | 696 editor.putLong(PREF_TIMESTAMP_OF_REQUEST, |
732 hasRequest() ? mCurrentRequest.getCreationTimestamp() : INVALID_ TIMESTAMP); | 697 hasRequest() ? mCurrentRequest.getCreationTimestamp() : INVALID_ TIMESTAMP); |
733 editor.putString(PREF_PERSISTED_REQUEST_ID, | 698 editor.putString(PREF_PERSISTED_REQUEST_ID, |
734 hasRequest() ? mCurrentRequest.getRequestID() : INVALID_REQUEST_ ID); | 699 hasRequest() ? mCurrentRequest.getRequestID() : INVALID_REQUEST_ ID); |
735 editor.putString(PREF_LATEST_VERSION, mLatestVersion == null ? "" : mLat estVersion); | 700 editor.putString(PREF_LATEST_VERSION, mLatestVersion == null ? "" : mLat estVersion); |
736 editor.putString(PREF_MARKET_URL, mMarketURL == null ? "" : mMarketURL); | 701 editor.putString(PREF_MARKET_URL, mMarketURL == null ? "" : mMarketURL); |
737 | 702 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
811 Boolean value = (Boolean) items.get(key); | 776 Boolean value = (Boolean) items.get(key); |
812 return value != null ? value : defaultValue; | 777 return value != null ? value : defaultValue; |
813 } | 778 } |
814 | 779 |
815 /** | 780 /** |
816 * @return Whether it is either a fresh install or data has been cleared. | 781 * @return Whether it is either a fresh install or data has been cleared. |
817 * PREF_TIMESTAMP_OF_INSTALL is set within the first few seconds after a fre sh install. | 782 * PREF_TIMESTAMP_OF_INSTALL is set within the first few seconds after a fre sh install. |
818 * sIsFreshInstallOrDataCleared will be set to true if PREF_TIMESTAMP_OF_INS TALL has not | 783 * sIsFreshInstallOrDataCleared will be set to true if PREF_TIMESTAMP_OF_INS TALL has not |
819 * been previously set. Else, it will be set to false. sIsFreshInstallOrData Cleared is | 784 * been previously set. Else, it will be set to false. sIsFreshInstallOrData Cleared is |
820 * guarded by sLock. | 785 * guarded by sLock. |
821 * @param applicationContext The current application Context. | 786 * @param context The current Context. |
822 */ | 787 */ |
823 public static boolean isFreshInstallOrDataHasBeenCleared(Context application Context) { | 788 public static boolean isFreshInstallOrDataHasBeenCleared(Context context) { |
824 return setIsFreshInstallOrDataHasBeenCleared(applicationContext); | 789 return setIsFreshInstallOrDataHasBeenCleared(context); |
825 } | 790 } |
826 | 791 |
827 private static boolean setIsFreshInstallOrDataHasBeenCleared(Context applica tionContext) { | 792 private static boolean setIsFreshInstallOrDataHasBeenCleared(Context context ) { |
828 synchronized (sIsFreshInstallLock) { | 793 synchronized (sIsFreshInstallLock) { |
829 if (sIsFreshInstallOrDataCleared == null) { | 794 if (sIsFreshInstallOrDataCleared == null) { |
830 SharedPreferences prefs = applicationContext.getSharedPreference s( | 795 SharedPreferences prefs = context.getSharedPreferences( |
831 PREF_PACKAGE, Context.MODE_PRIVATE); | 796 PREF_PACKAGE, Context.MODE_PRIVATE); |
832 sIsFreshInstallOrDataCleared = (prefs.getLong(PREF_TIMESTAMP_OF_ INSTALL, -1) == -1); | 797 sIsFreshInstallOrDataCleared = (prefs.getLong(PREF_TIMESTAMP_OF_ INSTALL, -1) == -1); |
833 } | 798 } |
834 return sIsFreshInstallOrDataCleared; | 799 return sIsFreshInstallOrDataCleared; |
835 } | 800 } |
836 } | 801 } |
802 | |
803 protected final RequestGenerator getRequestGenerator() { | |
804 if (mGenerator == null) mGenerator = createRequestGenerator(this); | |
805 return mGenerator; | |
806 } | |
807 | |
808 protected final ExponentialBackoffScheduler getBackoffScheduler() { | |
809 if (mBackoffScheduler == null) { | |
810 mBackoffScheduler = createBackoffScheduler( | |
811 PREF_PACKAGE, this, MS_POST_BASE_DELAY, MS_POST_MAX_DELAY); | |
812 } | |
813 return mBackoffScheduler; | |
814 } | |
837 } | 815 } |
OLD | NEW |