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

Side by Side Diff: chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaClientTest.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.omaha;
6
7 import static org.chromium.chrome.test.omaha.MockRequestGenerator.DeviceType;
8
9 import android.app.AlarmManager;
10 import android.app.PendingIntent;
11 import android.content.ComponentName;
12 import android.content.Context;
13 import android.content.Intent;
14 import android.content.SharedPreferences;
15 import android.content.pm.ApplicationInfo;
16 import android.test.InstrumentationTestCase;
17 import android.test.suitebuilder.annotation.SmallTest;
18
19 import org.chromium.base.test.util.AdvancedMockContext;
20 import org.chromium.base.test.util.Feature;
21 import org.chromium.chrome.test.omaha.AttributeFinder;
22 import org.chromium.chrome.test.omaha.MockRequestGenerator;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.net.HttpURLConnection;
30 import java.net.MalformedURLException;
31 import java.net.SocketTimeoutException;
32 import java.net.URL;
33 import java.util.HashSet;
34 import java.util.LinkedList;
35
36 /**
37 * Tests for the {@link OmahaClient}.
38 * Tests often override the original OmahaClient's functions with the HookedOmah aClient, which
39 * provides a way to hook into functions to return values that would normally be provided by the
40 * system, such as whether Chrome was installed through the system image.
41 */
42 public class OmahaClientTest extends InstrumentationTestCase {
43 private enum ServerResponse {
44 SUCCESS, FAILURE
45 }
46
47 private enum ConnectionStatus {
48 RESPONDS, TIMES_OUT
49 }
50
51 private enum InstallEvent {
52 SEND, DONT_SEND
53 }
54
55 private enum ForceTest {
56 FORCED, NOT_FORCED
57 }
58
59 private enum PostStatus {
60 DUE, NOT_DUE
61 }
62
63 private MockOmahaContext mContext;
64 private HookedOmahaClient mOmahaClient;
65
66 @Override
67 protected void setUp() {
68 Context targetContext = getInstrumentation().getTargetContext();
69 mContext = new MockOmahaContext(targetContext);
70 mOmahaClient = HookedOmahaClient.create(mContext);
71 }
72
73 /**
74 * If a request exists during handleInitialize(), a POST Intent should be fi red immediately.
75 */
76 @SmallTest
77 @Feature({"Omaha"})
78 public void testInitializeWithRequest() {
79 mOmahaClient.registerNewRequest(10);
80
81 Intent intent = OmahaClient.createInitializeIntent(mContext);
82 mOmahaClient.onHandleIntent(intent);
83 assertTrue("OmahaClient has no registered request", mOmahaClient.hasRequ est());
84 assertTrue("Alarm does not have the correct state", mOmahaClient.getRequ estAlarmWasSet());
85 assertTrue("OmahaClient wasn't restarted.", mContext.mOmahaClientRestart ed);
86 assertNotNull(mContext.mIntentFired);
87 assertEquals("POST intent not fired.",
88 OmahaClient.createPostRequestIntent(mContext, false).getAction() ,
89 mContext.mIntentFired.getAction());
90 }
91
92 /**
93 * If a request doesn't exist during handleInitialize(), no intent should be fired.
94 */
95 @SmallTest
96 @Feature({"Omaha"})
97 public void testInitializeWithoutRequest() {
98 Intent intent = OmahaClient.createInitializeIntent(mContext);
99 mOmahaClient.onHandleIntent(intent);
100 assertFalse("OmahaClient has a registered request", mOmahaClient.hasRequ est());
101 assertTrue("Alarm does not have the correct state", mOmahaClient.getRequ estAlarmWasSet());
102 assertFalse("OmahaClient was restarted.", mContext.mOmahaClientRestarted );
103 assertNull(mContext.mIntentFired);
104 }
105
106 /**
107 * Catch situations where the install source isn't set prior to restoring a saved request.
108 */
109 @SmallTest
110 @Feature({"Omaha"})
111 public void testInstallSourceSetBeforeRestoringRequest() {
112 // Plant a failed request.
113 Context targetContext = getInstrumentation().getTargetContext();
114 MockOmahaContext mockContext = new MockOmahaContext(targetContext);
115 SharedPreferences prefs =
116 mockContext.getSharedPreferences(OmahaClient.PREF_PACKAGE, Conte xt.MODE_PRIVATE);
117 SharedPreferences.Editor editor = prefs.edit();
118 editor.putLong(OmahaClient.PREF_TIMESTAMP_OF_REQUEST, 0);
119 editor.putString(OmahaClient.PREF_PERSISTED_REQUEST_ID, "persisted_id");
120 editor.apply();
121
122 // Send it off and don't crash when the state is restored and the XML is generated.
123 HookedOmahaClient omahaClient = HookedOmahaClient.create(mockContext);
124 omahaClient.mMockScheduler.setCurrentTime(1000);
125 Intent postIntent = OmahaClient.createPostRequestIntent(mockContext, fal se);
126 omahaClient.onHandleIntent(postIntent);
127
128 // Check that the request was actually generated and tried to be sent.
129 MockConnection connection = omahaClient.getLastConnection();
130 assertTrue("Didn't try to make a connection.", connection.getSentRequest ());
131 assertFalse("OmahaClient still has a registered request", omahaClient.ha sRequest());
132 assertTrue("Failed to send request", omahaClient.getCumulativeFailedAtte mpts() == 0);
133 }
134
135 /**
136 * Makes sure that we don't generate a request if we don't have to.
137 */
138 @SmallTest
139 @Feature({"Omaha", "Main"})
140 public void testOmahaClientDoesNotGenerateRequest() {
141 // Change the time so the OmahaClient thinks no request is necessary.
142 mOmahaClient.mMockScheduler.setCurrentTime(-1000);
143 Intent intent = OmahaClient.createRegisterRequestIntent(mContext, false) ;
144 mOmahaClient.onHandleIntent(intent);
145 assertFalse("OmahaClient has a registered request", mOmahaClient.hasRequ est());
146 assertFalse("OmahaClient was relaunched", mContext.mOmahaClientRestarted );
147 }
148
149 /**
150 * Makes sure that firing a XML request triggers a post intent.
151 */
152 @SmallTest
153 @Feature({"Omaha", "Main"})
154 public void testOmahaClientRequestToPost() {
155 // Change the time so the OmahaClient thinks a request is overdue.
156 mOmahaClient.mMockScheduler.setCurrentTime(1000);
157 Intent intent = OmahaClient.createRegisterRequestIntent(mContext, false) ;
158 mOmahaClient.onHandleIntent(intent);
159 assertTrue("OmahaClient has no registered request", mOmahaClient.hasRequ est());
160 assertTrue("OmahaClient wasn't relaunched", mContext.mOmahaClientRestart ed);
161 }
162
163 /**
164 * Makes sure that forcing an XML request generates a request and triggers a post intent.
165 */
166 @SmallTest
167 @Feature({"Omaha", "Main"})
168 public void testOmahaClientForcedRequestToPost() {
169 Intent intent = OmahaClient.createRegisterRequestIntent(mContext, true);
170 mOmahaClient.onHandleIntent(intent);
171 assertTrue("OmahaClient has no registered request", mOmahaClient.hasRequ est());
172 assertTrue("OmahaClient wasn't relaunched", mContext.mOmahaClientRestart ed);
173 }
174
175 /**
176 * Makes sure that incorrect timestamps are caught.
177 */
178 @SmallTest
179 @Feature({"Omaha"})
180 public void testIncorrectDelays() {
181 // Set the time to be 2 days past epoch, then generate a request.
182 final long millisecondsPerDay = 86400000;
183 long currentTimestamp = millisecondsPerDay * 2;
184 mOmahaClient.mMockScheduler.setCurrentTime(currentTimestamp);
185 mOmahaClient.registerNewRequest(currentTimestamp);
186
187 // Rewind the clock 2 days.
188 currentTimestamp -= millisecondsPerDay * 2;
189 mOmahaClient.mMockScheduler.setCurrentTime(currentTimestamp);
190 mOmahaClient.restoreState();
191
192 // Confirm that the post timestamp was reset, since it's larger than the exponential
193 // backoff delay.
194 assertEquals("Post timestamp was not cleared.",
195 mOmahaClient.getTimestampForNextPostAttempt(), 0);
196
197 // Confirm that the request timestamp was reset, since the next timestam p is more than
198 // a day away.
199 assertEquals("Request timestamp was not cleared.",
200 mOmahaClient.getTimestampForNewRequest(), 0);
201 }
202
203 /**
204 * Checks that reading and writing out the preferences works.
205 */
206 @SmallTest
207 @Feature({"Omaha"})
208 public void testOmahaClientFileIO() {
209 // Register a request and save it to disk.
210 mOmahaClient.registerNewRequest(0);
211
212 // The second OmahaCLient should retrieve the request that the first one saved.
213 HookedOmahaClient secondClient = HookedOmahaClient.create(mContext);
214 assertTrue("The request from the first OmahaClient wasn't written",
215 secondClient.hasRequest());
216 }
217
218 @SmallTest
219 @Feature({"Omaha"})
220 public void testOmahaClientPostHandsetFailure() {
221 postRequestToServer(DeviceType.HANDSET, ServerResponse.FAILURE, Connecti onStatus.RESPONDS,
222 InstallEvent.DONT_SEND, ForceTest.NOT_FORCED, PostSt atus.DUE);
223 }
224
225 @SmallTest
226 @Feature({"Omaha"})
227 public void testOmahaClientPostHandsetSuccess() {
228 postRequestToServer(DeviceType.HANDSET, ServerResponse.SUCCESS, Connecti onStatus.RESPONDS,
229 InstallEvent.DONT_SEND, ForceTest.NOT_FORCED, PostSt atus.DUE);
230 }
231
232 @SmallTest
233 @Feature({"Omaha"})
234 public void testOmahaClientPostTabletFailure() {
235 postRequestToServer(DeviceType.TABLET, ServerResponse.FAILURE, Connectio nStatus.RESPONDS,
236 InstallEvent.DONT_SEND, ForceTest.NOT_FORCED, PostSt atus.DUE);
237 }
238
239 @SmallTest
240 @Feature({"Omaha"})
241 public void testOmahaClientPostTabletSuccess() {
242 postRequestToServer(DeviceType.TABLET, ServerResponse.SUCCESS, Connectio nStatus.RESPONDS,
243 InstallEvent.DONT_SEND, ForceTest.NOT_FORCED, PostSt atus.DUE);
244 }
245
246 @SmallTest
247 @Feature({"Omaha"})
248 public void testOmahaClientPostHandsetTimeout() {
249 postRequestToServer(DeviceType.HANDSET, ServerResponse.FAILURE, Connecti onStatus.TIMES_OUT,
250 InstallEvent.DONT_SEND, ForceTest.NOT_FORCED, PostSt atus.DUE);
251 }
252
253 @SmallTest
254 @Feature({"Omaha"})
255 public void testOmahaClientPostInstallEventSuccess() {
256 postRequestToServer(DeviceType.HANDSET, ServerResponse.SUCCESS, Connecti onStatus.RESPONDS,
257 InstallEvent.SEND, ForceTest.NOT_FORCED, PostStatus. DUE);
258 }
259
260 @SmallTest
261 @Feature({"Omaha"})
262 public void testOmahaClientPostInstallEventFailure() {
263 postRequestToServer(DeviceType.HANDSET, ServerResponse.FAILURE, Connecti onStatus.RESPONDS,
264 InstallEvent.SEND, ForceTest.NOT_FORCED, PostStatus. DUE);
265 }
266
267 @SmallTest
268 @Feature({"Omaha"})
269 public void testOmahaClientPostForcedPostWhenNotDue() {
270 postRequestToServer(DeviceType.HANDSET, ServerResponse.SUCCESS, Connecti onStatus.RESPONDS,
271 InstallEvent.DONT_SEND, ForceTest.FORCED, PostStatus .NOT_DUE);
272 }
273
274 @SmallTest
275 @Feature({"Omaha"})
276 public void testOmahaClientPostWhenNotDue() {
277 postRequestToServer(DeviceType.HANDSET, ServerResponse.FAILURE, Connecti onStatus.RESPONDS,
278 InstallEvent.DONT_SEND, ForceTest.NOT_FORCED, PostSt atus.NOT_DUE);
279 }
280
281 /**
282 * Pretends to post a request to the Omaha server.
283 * @param deviceType Whether or not to use an app-ID indicating a tablet.
284 * @param response Whether the server acknowledged the request correctly.
285 * @param connectionStatus Whether the connection times out when it tries to contact the
286 * Omaha server.
287 * @param installType Whether we're sending an install event or not.
288 * @param forceType Whether we're testing POSTing a request, regardless of t imers.
289 * @param postStatus Whether we're due for a POST or not.
290 */
291 public void postRequestToServer(DeviceType deviceType, ServerResponse respon se,
292 ConnectionStatus connectionStatus, InstallEvent installType, ForceTe st forceType,
293 PostStatus postStatus) {
294 final boolean succeeded = response == ServerResponse.SUCCESS;
295 final boolean sentInstallEvent = installType == InstallEvent.SEND;
296
297 HookedOmahaClient omahaClient = new HookedOmahaClient(mContext, deviceTy pe, response,
298 connectionStatus, false);
299 omahaClient.onCreate();
300 omahaClient.restoreState();
301
302 // Set whether or not we're sending the install event.
303 assertTrue("Should default to sending install event.", omahaClient.isSen dInstallEvent());
304 omahaClient.setSendInstallEvent(installType == InstallEvent.SEND);
305 omahaClient.registerNewRequest(0);
306
307 // Set up the POST request.
308 if (postStatus == PostStatus.NOT_DUE) {
309 // Rewind the clock so that we don't send the request yet.
310 omahaClient.mMockScheduler.setCurrentTime(-1000);
311 }
312 Intent postIntent =
313 OmahaClient.createPostRequestIntent(mContext, forceType == Force Test.FORCED);
314 omahaClient.onHandleIntent(postIntent);
315
316 assertTrue("hasRequest() returned wrong value", succeeded != omahaClient .hasRequest());
317 if (postStatus == PostStatus.NOT_DUE && forceType == ForceTest.NOT_FORCE D) {
318 // No POST attempt was made.
319 assertTrue("POST was attempted and failed.",
320 omahaClient.getCumulativeFailedAttempts() == 0);
321 assertTrue("POST alarm wasn't set for reattempt", omahaClient.getPOS TAlarmWasSet());
322 } else {
323 // Since we start with no failures, the counter incrementing should indicate whether it
324 // succeeded or not.
325 assertEquals("Expected different outcome", succeeded,
326 omahaClient.getCumulativeFailedAttempts() == 0);
327 assertTrue("Alarm state was changed when it shouldn't have been",
328 succeeded != omahaClient.getPOSTAlarmWasSet());
329
330 // If we're sending an install event, we will immediately attempt to send a ping in a
331 // follow-up request.
332 int numExpectedRequests = succeeded && sentInstallEvent ? 2 : 1;
333 assertEquals("Didn't send the correct number of XML requests.", numE xpectedRequests,
334 omahaClient.getNumConnectionsMade());
335
336 MockConnection connection = omahaClient.getLastConnection();
337 assertEquals("Didn't try to make a connection.", true, connection.ge tSentRequest());
338
339 if (connectionStatus == ConnectionStatus.TIMES_OUT) {
340 // Several events shouldn't happen if the connection times out.
341 assertEquals("Retrieved response code when it should have bailed earlier.",
342 0, connection.getNumTimesResponseCodeRetrieved());
343 assertFalse("Grabbed input stream when it should have bailed ear lier.",
344 connection.getGotInputStream());
345 }
346 }
347
348 // Check that the latest version and market URLs were saved correctly.
349 String expectedVersion = succeeded ? MockConnection.UPDATE_VERSION : "";
350 String expectedURL = succeeded ? MockConnection.STRIPPED_MARKET_URL : "" ;
351
352 // Make sure we properly parsed out the server's response.
353 assertEquals("Latest version numbers didn't match", expectedVersion,
354 OmahaClient.getVersionNumberGetter().getLatestKnownVersion(
355 mContext, OmahaClient.PREF_PACKAGE, OmahaClient.PREF_LAT EST_VERSION));
356 assertEquals("Market URL didn't match", expectedURL, OmahaClient.getMark etURL(mContext));
357
358 // Check that the install event was sent properly.
359 if (sentInstallEvent) {
360 assertFalse("OmahaPingService is going to send another install <even t>.",
361 succeeded == omahaClient.isSendInstallEvent());
362 }
363 }
364
365 /**
366 * Test whether we're using request and session IDs properly for POSTs.
367 */
368 @SmallTest
369 @Feature({"Omaha"})
370 public void testRequestAndSessionIDs() {
371 assertTrue("Should default to sending install event.", mOmahaClient.isSe ndInstallEvent());
372
373 // Send the POST request.
374 mOmahaClient.registerNewRequest(0);
375 Intent postIntent = OmahaClient.createPostRequestIntent(mContext, true);
376 mOmahaClient.onHandleIntent(postIntent);
377
378 // If we're sending an install event, we will immediately attempt to sen d a ping in a
379 // follow-up request. These should have the same session ID, but differ ent request IDs.
380 int numRequests = mOmahaClient.getNumConnectionsMade();
381
382 HashSet<String> sessionIDs = new HashSet<String>();
383 HashSet<String> requestIDs = new HashSet<String>();
384 for (int i = 0; i < numRequests; ++i) {
385 String request = mOmahaClient.getConnection(i).getOutputStreamConten ts();
386
387 String sessionID =
388 new AttributeFinder(request, "request", "sessionid").getValu e();
389 assertNotNull(sessionID);
390 sessionIDs.add(sessionID);
391
392 String requestID =
393 new AttributeFinder(request, "request", "requestid").getValu e();
394 assertNotNull(requestID);
395 requestIDs.add(requestID);
396 }
397 assertEquals("Session ID was not the same across all requests", 1,
398 sessionIDs.size());
399 assertEquals("Request ID was duplicated", numRequests, requestIDs.size() );
400
401 // Send another XML request and make sure the IDs are all different.
402 assertFalse("OmahaPingService is going to send another install <event>." ,
403 mOmahaClient.isSendInstallEvent());
404 mOmahaClient.registerNewRequest(0);
405 postIntent = OmahaClient.createPostRequestIntent(mContext, true);
406 mOmahaClient.onHandleIntent(postIntent);
407
408 assertEquals("Didn't send the correct number of XML requests.", numReque sts + 1,
409 mOmahaClient.getNumConnectionsMade());
410 String newRequest = mOmahaClient.getConnection(numRequests).getOutputStr eamContents();
411
412 String newSessionID = new AttributeFinder(newRequest, "request", "sessio nid").getValue();
413 assertNotNull(newSessionID);
414 assertFalse("Session ID was reused.", sessionIDs.contains(newSessionID)) ;
415
416 String newRequestID = new AttributeFinder(newRequest, "request", "reques tid").getValue();
417 assertNotNull(newRequestID);
418 assertFalse("Request ID was reused.", requestIDs.contains(newRequestID)) ;
419 }
420
421 /**
422 * Checks to see that the header is added only for persisted XML requests.
423 */
424 @SmallTest
425 @Feature({"Omaha"})
426 public void testHTTPHeaderForPersistedXMLRequest() {
427 final String xml = "<lorem ipsum=\"dolor\" />";
428 final long requestTimestamp = 0;
429 final long currentTimestamp = 11684;
430 final long currentTimestampInSeconds = currentTimestamp / 1000;
431
432 mOmahaClient.registerNewRequest(requestTimestamp);
433
434 assertTrue("Should default to sending install event.", mOmahaClient.isSe ndInstallEvent());
435 assertEquals("Shouldn't have any failed attempts.", 0,
436 mOmahaClient.getCumulativeFailedAttempts());
437
438 MockConnection connection = null;
439 try {
440 mOmahaClient.postRequest(currentTimestamp, xml);
441 connection = mOmahaClient.getLastConnection();
442 } catch (RequestFailureException e) {
443 fail();
444 }
445 assertEquals("Age property field was unexpectedly added.", null,
446 connection.getRequestPropertyField());
447 assertEquals("Age property value was unexpectedly set.", null,
448 connection.getRequestPropertyValue());
449
450 // Fail once, then check that the header is added.
451 mOmahaClient.getBackoffScheduler().increaseFailedAttempts();
452 try {
453 mOmahaClient.postRequest(currentTimestamp, xml);
454 connection = mOmahaClient.getLastConnection();
455 } catch (RequestFailureException e) {
456 fail();
457 }
458 assertEquals("Age property field was not added.", "X-RequestAge",
459 connection.getRequestPropertyField());
460 assertEquals("Age property value was incorrectly set.", currentTimestamp InSeconds,
461 Long.parseLong(connection.getRequestPropertyValue()));
462
463 // Make sure the header isn't added if we're not sending an install ping .
464 mOmahaClient.setSendInstallEvent(false);
465 mOmahaClient.registerNewRequest(requestTimestamp);
466 mOmahaClient.getBackoffScheduler().increaseFailedAttempts();
467 try {
468 mOmahaClient.postRequest(currentTimestamp, xml);
469 connection = mOmahaClient.getLastConnection();
470 } catch (RequestFailureException e) {
471 fail();
472 }
473 assertEquals("Age property field was unexpectedly added.", null,
474 connection.getRequestPropertyField());
475 assertEquals("Age property value was unexpectedly set.", null,
476 connection.getRequestPropertyValue());
477 }
478
479 @SmallTest
480 @Feature({"Omaha"})
481 public void testInstallSource() {
482 HookedOmahaClient organicClient = new HookedOmahaClient(mContext, Device Type.TABLET,
483 ServerResponse.SUCCESS, ConnectionStatus.RESPONDS, false);
484 String organicInstallSource = organicClient.determineInstallSource(mCont ext);
485 assertEquals("Install source should have been treated as organic.",
486 OmahaClient.INSTALL_SOURCE_ORGANIC, organicInstallSource);
487
488 HookedOmahaClient systemImageClient = new HookedOmahaClient(mContext, De viceType.TABLET,
489 ServerResponse.SUCCESS, ConnectionStatus.RESPONDS, true);
490 String systemImageInstallSource = systemImageClient.determineInstallSour ce(mContext);
491 assertEquals("Install source should have been treated as system image.",
492 OmahaClient.INSTALL_SOURCE_SYSTEM, systemImageInstallSource);
493 }
494
495 /**
496 * OmahaClient that overrides simple methods for testing.
497 */
498 private static class HookedOmahaClient extends OmahaClient {
499 private final boolean mIsOnTablet;
500 private final boolean mSendValidResponse;
501 private final boolean mIsInForeground;
502 private final boolean mConnectionTimesOut;
503 private final boolean mInstalledOnSystemImage;
504
505 private MockExponentialBackoffScheduler mMockScheduler;
506 private RequestGenerator mMockGenerator;
507 private final LinkedList<MockConnection> mMockConnections;
508
509 private boolean mRequestAlarmWasSet;
510 private int mNumUUIDsGenerated;
511
512 public static HookedOmahaClient create(Context context) {
513 HookedOmahaClient omahaClient = new HookedOmahaClient(context, Devic eType.TABLET,
514 ServerResponse.SUCCESS, ConnectionStatus.RESPONDS, false);
515 omahaClient.onCreate();
516 omahaClient.restoreState();
517 return omahaClient;
518 }
519
520 public HookedOmahaClient(Context context, DeviceType deviceType,
521 ServerResponse serverResponse, ConnectionStatus connectionSt atus,
522 boolean installedOnSystemImage) {
523 attachBaseContext(context);
524 mIsOnTablet = deviceType == DeviceType.TABLET;
525 mSendValidResponse = serverResponse == ServerResponse.SUCCESS;
526 mIsInForeground = true;
527 mConnectionTimesOut = connectionStatus == ConnectionStatus.TIMES_OUT ;
528 mMockConnections = new LinkedList<MockConnection>();
529 mInstalledOnSystemImage = installedOnSystemImage;
530 }
531
532 @Override
533 protected boolean isChromeBeingUsed() {
534 return mIsInForeground;
535 }
536
537 @Override
538 public int getApplicationFlags() {
539 return mInstalledOnSystemImage ? ApplicationInfo.FLAG_SYSTEM : 0;
540 }
541
542 /**
543 * Checks if an alarm was set by the backoff scheduler.
544 */
545 public boolean getPOSTAlarmWasSet() {
546 return mMockScheduler.getAlarmWasSet();
547 }
548
549 public boolean getRequestAlarmWasSet() {
550 return mRequestAlarmWasSet;
551 }
552
553 /**
554 * Gets the number of MockConnections created.
555 */
556 public int getNumConnectionsMade() {
557 return mMockConnections.size();
558 }
559
560 /**
561 * Returns a particular connection.
562 */
563 public MockConnection getConnection(int index) {
564 return mMockConnections.get(index);
565 }
566
567 /**
568 * Returns the last MockPingConection used to simulate communication wit h the server.
569 */
570 public MockConnection getLastConnection() {
571 return mMockConnections.getLast();
572 }
573
574 public boolean isSendInstallEvent() {
575 return mSendInstallEvent;
576 }
577
578 public void setSendInstallEvent(boolean state) {
579 mSendInstallEvent = state;
580 }
581
582 MockExponentialBackoffScheduler getBackoffScheduler() {
583 return mMockScheduler;
584 }
585
586 /**
587 * Mocks out the scheduler so that no alarms are really created.
588 */
589 @Override
590 ExponentialBackoffScheduler createBackoffScheduler(String prefPackage, C ontext context,
591 long base, long max) {
592 mMockScheduler = new MockExponentialBackoffScheduler(prefPackage, co ntext, base, max);
593 return mMockScheduler;
594 }
595
596 @Override
597 RequestGenerator createRequestGenerator(Context context) {
598 mMockGenerator = new MockRequestGenerator(
599 context, mIsOnTablet ? DeviceType.TABLET : DeviceType.HANDSE T);
600 return mMockGenerator;
601 }
602
603 @Override
604 protected HttpURLConnection createConnection() throws RequestFailureExce ption {
605 MockConnection connection = null;
606 try {
607 URL url = new URL(mMockGenerator.getServerUrl());
608 connection = new MockConnection(url, mIsOnTablet, mSendValidResp onse,
609 mSendInstallEvent, mConnectionTimesOut);
610 mMockConnections.addLast(connection);
611 } catch (MalformedURLException e) {
612 fail("Caught a malformed URL exception: " + e);
613 }
614 return connection;
615 }
616
617 @Override
618 protected void setAlarm(AlarmManager am, PendingIntent operation, int al armType,
619 long triggerAtTime) {
620 mRequestAlarmWasSet = true;
621 }
622
623 @Override
624 protected String generateRandomUUID() {
625 mNumUUIDsGenerated += 1;
626 return "UUID" + mNumUUIDsGenerated;
627 }
628 }
629
630
631 /**
632 * Simulates communication with the actual Omaha server.
633 */
634 private static class MockConnection extends HttpURLConnection {
635 // Omaha appends a "/" to the URL.
636 private static final String STRIPPED_MARKET_URL =
637 "https://market.android.com/details?id=com.google.android.apps.c hrome";
638 private static final String MARKET_URL = STRIPPED_MARKET_URL + "/";
639
640 private static final String UPDATE_VERSION = "1.2.3.4";
641
642 // Parameters.
643 private final boolean mConnectionTimesOut;
644 private final ByteArrayInputStream mServerResponse;
645 private final ByteArrayOutputStream mOutputStream;
646 private final int mHTTPResponseCode;
647
648 // Result variables.
649 private int mContentLength;
650 private int mNumTimesResponseCodeRetrieved;
651 private boolean mSentRequest;
652 private boolean mGotInputStream;
653 private String mRequestPropertyField;
654 private String mRequestPropertyValue;
655
656 MockConnection(URL url, boolean usingTablet, boolean sendValidResponse,
657 boolean sendInstallEvent, boolean connectionTimesOut) {
658 super(url);
659 assertEquals(MockRequestGenerator.SERVER_URL, url.toString());
660
661 String mockResponse = buildServerResponseString(usingTablet, sendIns tallEvent);
662 mOutputStream = new ByteArrayOutputStream();
663 mServerResponse = new ByteArrayInputStream(mockResponse.getBytes());
664 mConnectionTimesOut = connectionTimesOut;
665
666 if (sendValidResponse) {
667 mHTTPResponseCode = 200;
668 } else {
669 mHTTPResponseCode = 404;
670 }
671 }
672
673 /**
674 * Build a simulated response from the Omaha server indicating an update is available.
675 * The response changes based on the device type.
676 */
677 private String buildServerResponseString(boolean isOnTablet, boolean sen dInstallEvent) {
678 String response = "";
679 response += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
680 response += "<response protocol=\"3.0\" server=\"prod\">";
681 response += "<daystart elapsed_seconds=\"12345\"/>";
682 response += "<app appid=\"";
683 response += (isOnTablet
684 ? MockRequestGenerator.UUID_TABLET : MockRequestGenerator.UU ID_PHONE);
685 response += "\" status=\"ok\">";
686 if (sendInstallEvent) {
687 response += "<event status=\"ok\"/>";
688 } else {
689 response += "<updatecheck status=\"ok\">";
690 response += "<urls><url codebase=\"" + MARKET_URL + "\"/></urls> ";
691 response += "<manifest version=\"" + UPDATE_VERSION + "\">";
692 response += "<packages>";
693 response += "<package hash=\"0\" name=\"dummy.apk\" required=\"t rue\" size=\"0\"/>";
694 response += "</packages>";
695 response += "<actions>";
696 response += "<action event=\"install\" run=\"dummy.apk\"/>";
697 response += "<action event=\"postinstall\"/>";
698 response += "</actions>";
699 response += "</manifest>";
700 response += "</updatecheck>";
701 response += "<ping status=\"ok\"/>";
702 }
703 response += "</app>";
704 response += "</response>";
705 return response;
706 }
707
708 @Override
709 public boolean usingProxy() {
710 return false;
711 }
712
713 @Override
714 public void connect() throws SocketTimeoutException {
715 if (mConnectionTimesOut) {
716 throw new SocketTimeoutException("Connection timed out.");
717 }
718 }
719
720 @Override
721 public void disconnect() {}
722
723 @Override
724 public void setDoOutput(boolean value) throws IllegalAccessError {
725 assertTrue("Told the HTTPUrlConnection to send no request.", value);
726 }
727
728 @Override
729 public void setFixedLengthStreamingMode(int contentLength) {
730 mContentLength = contentLength;
731 }
732
733 @Override
734 public int getResponseCode() {
735 if (mNumTimesResponseCodeRetrieved == 0) {
736 // The output stream should now have the generated XML for the r equest.
737 // Check if its length is correct.
738 assertEquals("Expected OmahaClient to write out certain number o f bytes",
739 mContentLength, mOutputStream.toByteArray().length);
740 }
741 assertTrue("Tried to retrieve response code more than twice",
742 mNumTimesResponseCodeRetrieved < 2);
743 mNumTimesResponseCodeRetrieved++;
744 return mHTTPResponseCode;
745 }
746
747 @Override
748 public OutputStream getOutputStream() throws IOException {
749 mSentRequest = true;
750 connect();
751 return mOutputStream;
752 }
753
754 public String getOutputStreamContents() {
755 return mOutputStream.toString();
756 }
757
758 @Override
759 public InputStream getInputStream() {
760 assertTrue("Tried to read server response without sending request.", mSentRequest);
761 mGotInputStream = true;
762 return mServerResponse;
763 }
764
765 @Override
766 public void addRequestProperty(String field, String newValue) {
767 mRequestPropertyField = field;
768 mRequestPropertyValue = newValue;
769 }
770
771 public int getNumTimesResponseCodeRetrieved() {
772 return mNumTimesResponseCodeRetrieved;
773 }
774
775 public boolean getGotInputStream() {
776 return mGotInputStream;
777 }
778
779 public boolean getSentRequest() {
780 return mSentRequest;
781 }
782
783 public String getRequestPropertyField() {
784 return mRequestPropertyField;
785 }
786
787 public String getRequestPropertyValue() {
788 return mRequestPropertyValue;
789 }
790 }
791
792 private static class MockOmahaContext extends AdvancedMockContext {
793 private boolean mOmahaClientRestarted;
794 private Intent mIntentFired;
795
796 public MockOmahaContext(Context targetContext) {
797 super(targetContext);
798 }
799
800 @Override
801 public ComponentName startService(Intent intent) {
802 assertEquals(OmahaClient.class.getCanonicalName(),
803 intent.getComponent().getClassName());
804 mOmahaClientRestarted = true;
805 mIntentFired = intent;
806 return intent.getComponent();
807 }
808 }
809 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698