• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.android.libraries.mobiledatadownload;
17 
18 import static com.google.android.libraries.mobiledatadownload.testing.MddTestDependencies.ExecutorType;
19 import static com.google.common.truth.Truth.assertThat;
20 import static java.util.concurrent.TimeUnit.DAYS;
21 import static java.util.concurrent.TimeUnit.SECONDS;
22 import static org.mockito.Mockito.eq;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 
26 import android.app.blob.BlobStoreManager;
27 import android.content.Context;
28 import android.net.Uri;
29 import android.util.Log;
30 import androidx.test.core.app.ApplicationProvider;
31 import com.google.android.libraries.mobiledatadownload.downloader.FileDownloader;
32 import com.google.android.libraries.mobiledatadownload.file.SynchronousFileStorage;
33 import com.google.android.libraries.mobiledatadownload.file.backends.AndroidFileBackend;
34 import com.google.android.libraries.mobiledatadownload.file.backends.BlobStoreBackend;
35 import com.google.android.libraries.mobiledatadownload.file.backends.BlobUri;
36 import com.google.android.libraries.mobiledatadownload.file.backends.JavaFileBackend;
37 import com.google.android.libraries.mobiledatadownload.file.transforms.CompressTransform;
38 import com.google.android.libraries.mobiledatadownload.internal.MddTestUtil;
39 import com.google.android.libraries.mobiledatadownload.monitor.DownloadProgressMonitor;
40 import com.google.android.libraries.mobiledatadownload.monitor.NetworkUsageMonitor;
41 import com.google.android.libraries.mobiledatadownload.testing.TestFileDownloader;
42 import com.google.android.libraries.mobiledatadownload.testing.TestFlags;
43 import com.google.common.base.Optional;
44 import com.google.common.base.Supplier;
45 import com.google.common.collect.ImmutableList;
46 import com.google.common.util.concurrent.ListeningExecutorService;
47 import com.google.common.util.concurrent.MoreExecutors;
48 import com.google.mobiledatadownload.ClientConfigProto.ClientFile;
49 import com.google.mobiledatadownload.ClientConfigProto.ClientFileGroup;
50 import com.google.mobiledatadownload.DownloadConfigProto.DataFileGroup;
51 import com.google.mobiledatadownload.DownloadConfigProto.DownloadConditions.DeviceNetworkPolicy;
52 import com.google.mobiledatadownload.LogProto.DataDownloadFileGroupStats;
53 import com.google.mobiledatadownload.LogProto.MddLogData;
54 import com.google.testing.junit.testparameterinjector.TestParameter;
55 import com.google.testing.junit.testparameterinjector.TestParameterInjector;
56 import java.util.List;
57 import java.util.concurrent.Executors;
58 import java.util.concurrent.ScheduledExecutorService;
59 import org.junit.After;
60 import org.junit.Before;
61 import org.junit.Rule;
62 import org.junit.Test;
63 import org.junit.runner.RunWith;
64 import org.mockito.ArgumentCaptor;
65 import org.mockito.Mock;
66 import org.mockito.junit.MockitoJUnit;
67 import org.mockito.junit.MockitoRule;
68 
69 @RunWith(TestParameterInjector.class)
70 public final class MddGarbageCollectionWithAndroidSharingIntegrationTest {
71   private static final String TAG = "MddGarbageCollectionWithAndroidSharingIntegrationTest";
72   private static final int MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS = 300;
73 
74   private static final String TEST_DATA_RELATIVE_PATH =
75       "third_party/java_src/android_libs/mobiledatadownload/javatests/com/google/android/libraries/mobiledatadownload/testdata/";
76 
77   private static final ScheduledExecutorService DOWNLOAD_EXECUTOR =
78       Executors.newScheduledThreadPool(2);
79 
80   private static final String FILE_GROUP_TO_SHARE_1 = "test-group-1";
81   private static final String FILE_ID_1 = "test-file-to-share-1";
82   private static final String FILE_CHECKSUM_1 = "fcc96b272633cdf6c4bbd2d77512cca51bfb1dbd"; // SHA_1
83   static final String FILE_ANDROID_SHARING_CHECKSUM_1 =
84       "225017b5d5ec35732940af813b1ab7be5191e4c52659953e75a1a36a1398c48d"; // SHA_256
85   static final int FILE_SIZE_1 = 57;
86   static final String FILE_URL_1 = "https://www.gstatic.com/icing/idd/sample_group/step1.txt";
87 
88   private static final Context context = ApplicationProvider.getApplicationContext();
89 
90   @Mock private TaskScheduler mockTaskScheduler;
91   @Mock private NetworkUsageMonitor mockNetworkUsageMonitor;
92   @Mock private DownloadProgressMonitor mockDownloadProgressMonitor;
93   @Mock private Logger mockLogger;
94 
95   private SynchronousFileStorage fileStorage;
96 
97   private BlobStoreManager blobStoreManager;
98   private MobileDataDownload mobileDataDownload;
99   private Supplier<FileDownloader> fileDownloaderSupplier;
100   private ListeningExecutorService controlExecutor;
101 
102   private final TestFlags flags = new TestFlags();
103 
104   @Rule(order = 1)
105   public final MockitoRule mocks = MockitoJUnit.rule();
106 
107   @TestParameter ExecutorType controlExecutorType;
108 
109   @Before
setUp()110   public void setUp() throws Exception {
111 
112     // cl/439051122 created a temporary FALSE override targeted to ASGA devices. This test suite
113     // relies on garbage collection being enabled to test the metadata state transistions, but
114     // all_on testing doesn't respect diversion criteria in the launch.
115     //
116     // So we temporarily force it on to bypass the launch so the tests can rely on expected
117     // behavior.
118     // TODO(b/226551373): remove these overrides once AsgaDisableMddLibGcLaunch is turned down
119     flags.mddEnableGarbageCollection = Optional.of(true);
120 
121     flags.mddAndroidSharingSampleInterval = Optional.of(1);
122 
123     flags.mddDefaultSampleInterval = Optional.of(1);
124 
125     BlobStoreBackend blobStoreBackend = new BlobStoreBackend(context);
126     blobStoreManager = (BlobStoreManager) context.getSystemService(Context.BLOB_STORE_SERVICE);
127 
128     controlExecutor = controlExecutorType.executor();
129 
130     fileStorage =
131         new SynchronousFileStorage(
132             /* backends= */ ImmutableList.of(
133                 AndroidFileBackend.builder(context).build(),
134                 blobStoreBackend,
135                 new JavaFileBackend()),
136             /* transforms= */ ImmutableList.of(new CompressTransform()),
137             /* monitors= */ ImmutableList.of(mockNetworkUsageMonitor, mockDownloadProgressMonitor));
138 
139     fileDownloaderSupplier =
140         () ->
141             new TestFileDownloader(
142                 TEST_DATA_RELATIVE_PATH,
143                 fileStorage,
144                 MoreExecutors.listeningDecorator(DOWNLOAD_EXECUTOR));
145   }
146 
147   @After
tearDown()148   public void tearDown() throws Exception {
149     mobileDataDownload.clear().get();
150     // Commands to clean up the blob storage.
151     MddTestUtil.runShellCmd("cmd blob_store clear-all-sessions");
152     MddTestUtil.runShellCmd("cmd blob_store clear-all-blobs");
153   }
154 
downloadFileGroup(DataFileGroup fileGroup)155   private void downloadFileGroup(DataFileGroup fileGroup) throws Exception {
156     assertThat(
157             mobileDataDownload
158                 .addFileGroup(AddFileGroupRequest.newBuilder().setDataFileGroup(fileGroup).build())
159                 .get())
160         .isTrue();
161     mobileDataDownload
162         .downloadFileGroup(
163             DownloadFileGroupRequest.newBuilder()
164                 .setGroupName(fileGroup.getGroupName())
165                 .setListenerOptional(
166                     Optional.of(
167                         new DownloadListener() {
168                           @Override
169                           public void onProgress(long currentSize) {
170                             Log.i(TAG, "onProgress " + currentSize);
171                           }
172 
173                           @Override
174                           public void onComplete(ClientFileGroup clientFileGroup) {
175                             Log.i(TAG, "onComplete " + clientFileGroup.getGroupName());
176                           }
177                         }))
178                 .build())
179         .get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
180   }
181 
verifyDownloadedGroupIsDownloaded(DataFileGroup fileGroup, int fileCount)182   private ClientFileGroup verifyDownloadedGroupIsDownloaded(DataFileGroup fileGroup, int fileCount)
183       throws Exception {
184     ClientFileGroup clientFileGroup =
185         mobileDataDownload
186             .getFileGroup(
187                 GetFileGroupRequest.newBuilder().setGroupName(fileGroup.getGroupName()).build())
188             .get();
189 
190     assertThat(clientFileGroup).isNotNull();
191     assertThat(clientFileGroup.getGroupName()).isEqualTo(fileGroup.getGroupName());
192     assertThat(clientFileGroup.getFileCount()).isEqualTo(fileCount);
193     return clientFileGroup;
194   }
195 
196   @Test
deletesStaleGroups_staleLifetimeZero()197   public void deletesStaleGroups_staleLifetimeZero() throws Exception {
198     mobileDataDownload = builderForTest().build();
199     Uri androidUri =
200         BlobUri.builder(context).setBlobParameters(FILE_ANDROID_SHARING_CHECKSUM_1).build();
201     assertThat(fileStorage.exists(androidUri)).isFalse();
202 
203     // Download file group with stale lifetime 0.
204     DataFileGroup fileGroup =
205         TestFileGroupPopulator.createDataFileGroup(
206             FILE_GROUP_TO_SHARE_1,
207             context.getPackageName(),
208             new String[] {FILE_ID_1},
209             new int[] {FILE_SIZE_1},
210             new String[] {FILE_CHECKSUM_1},
211             new String[] {FILE_ANDROID_SHARING_CHECKSUM_1},
212             new String[] {FILE_URL_1},
213             DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
214 
215     downloadFileGroup(fileGroup);
216 
217     ClientFileGroup clientFileGroup = verifyDownloadedGroupIsDownloaded(fileGroup, 1);
218 
219     ClientFile clientFile = clientFileGroup.getFileList().get(0);
220     assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_1);
221     Uri uri = Uri.parse(clientFile.getFileUri());
222 
223     // The file is now available in the android shared storage.
224     assertThat(uri).isEqualTo(androidUri);
225     assertThat(fileStorage.exists(uri)).isTrue();
226     assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
227 
228     // Send an empty group so that the old group is now stale.
229     DataFileGroup emptyFileGroup =
230         TestFileGroupPopulator.createDataFileGroup(
231             FILE_GROUP_TO_SHARE_1,
232             context.getPackageName(),
233             new String[] {},
234             new int[] {},
235             new String[] {},
236             new String[] {},
237             new String[] {},
238             DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
239 
240     downloadFileGroup(emptyFileGroup);
241 
242     // Run maintenance taks.
243     mobileDataDownload.maintenance().get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
244 
245     verifyDownloadedGroupIsDownloaded(emptyFileGroup, 0);
246 
247     // Old stale file has been released
248     assertThat(blobStoreManager.getLeasedBlobs()).isEmpty();
249 
250     // Verify logging events.
251 
252     ArgumentCaptor<MddLogData> logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
253     // 1050 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
254     verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1050));
255     List<MddLogData> logData = logDataCaptor.getAllValues();
256     assertThat(logData).hasSize(1);
257 
258     DataDownloadFileGroupStats dataDownloadFileGroupStats =
259         logData.get(0).getDataDownloadFileGroupStats();
260     DataDownloadFileGroupStats staleGroupExpired =
261         DataDownloadFileGroupStats.newBuilder()
262             .setFileGroupName(fileGroup.getGroupName())
263             .setFileGroupVersionNumber(fileGroup.getFileGroupVersionNumber())
264             .setBuildId(0)
265             .setVariantId("")
266             .build();
267     assertThat(dataDownloadFileGroupStats).isEqualTo(staleGroupExpired);
268 
269     logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
270     // 1084 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED;
271     // Called once for every released lease.
272     verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1084));
273 
274     logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
275     // 1051 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
276     // It's logged once by mobileDataDownload.maintenance() and three times in the
277     // ExpirationHandler, once when the file metadata is deleted, once when the lease is released
278     // and once when the temporary local copy of the shared file is deleted.
279     verify(mockLogger, times(4)).log(logDataCaptor.capture(), /* eventCode= */ eq(1051));
280     logData = logDataCaptor.getAllValues();
281     assertThat(logData).hasSize(4);
282 
283     Void metadafileDeleted = null;
284     Void fileReleased = null;
285     Void fileDeleted = null;
286   }
287 
288   @Test
deletesStaleGroups_staleLifetimeTwoDays()289   public void deletesStaleGroups_staleLifetimeTwoDays() throws Exception {
290     mobileDataDownload = builderForTest().build();
291     Uri androidUri =
292         BlobUri.builder(context).setBlobParameters(FILE_ANDROID_SHARING_CHECKSUM_1).build();
293     assertThat(fileStorage.exists(androidUri)).isFalse();
294 
295     // Download file group with stale lifetime +2 days.
296     DataFileGroup fileGroup =
297         TestFileGroupPopulator.createDataFileGroup(
298             FILE_GROUP_TO_SHARE_1,
299             context.getPackageName(),
300             new String[] {FILE_ID_1},
301             new int[] {FILE_SIZE_1},
302             new String[] {FILE_CHECKSUM_1},
303             new String[] {FILE_ANDROID_SHARING_CHECKSUM_1},
304             new String[] {FILE_URL_1},
305             DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
306     fileGroup = fileGroup.toBuilder().setStaleLifetimeSecs(DAYS.toSeconds(2)).build();
307 
308     downloadFileGroup(fileGroup);
309 
310     ClientFileGroup clientFileGroup = verifyDownloadedGroupIsDownloaded(fileGroup, 1);
311 
312     ClientFile clientFile = clientFileGroup.getFileList().get(0);
313     assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_1);
314     Uri uri = Uri.parse(clientFile.getFileUri());
315 
316     // The file is now available in the android shared storage.
317     assertThat(uri).isEqualTo(androidUri);
318     assertThat(fileStorage.exists(uri)).isTrue();
319     assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
320 
321     // Send an empty group so that the old group is now stale.
322     DataFileGroup emptyFileGroup =
323         TestFileGroupPopulator.createDataFileGroup(
324             FILE_GROUP_TO_SHARE_1,
325             context.getPackageName(),
326             new String[] {},
327             new int[] {},
328             new String[] {},
329             new String[] {},
330             new String[] {},
331             DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
332     downloadFileGroup(emptyFileGroup);
333 
334     // Run maintenance taks.
335     mobileDataDownload.maintenance().get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
336 
337     verifyDownloadedGroupIsDownloaded(emptyFileGroup, 0);
338 
339     // Old stale file hasn't been released yet
340     assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
341 
342     // Advance time by 2 days, and verify that the lease on the shared file has been
343     // released.
344     MddTestUtil.timeTravel(context, DAYS.toMillis(2));
345     mobileDataDownload.maintenance().get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
346 
347     verifyDownloadedGroupIsDownloaded(emptyFileGroup, 0);
348 
349     assertThat(blobStoreManager.getLeasedBlobs()).isEmpty();
350 
351     // Verify logging events.
352 
353     ArgumentCaptor<MddLogData> logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
354     // 1050 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
355     verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1050));
356     List<MddLogData> logData = logDataCaptor.getAllValues();
357     assertThat(logData).hasSize(1);
358 
359     DataDownloadFileGroupStats dataDownloadFileGroupStats =
360         logData.get(0).getDataDownloadFileGroupStats();
361     DataDownloadFileGroupStats staleGroupExpired =
362         DataDownloadFileGroupStats.newBuilder()
363             .setFileGroupName(fileGroup.getGroupName())
364             .setFileGroupVersionNumber(fileGroup.getFileGroupVersionNumber())
365             .setBuildId(0)
366             .setVariantId("")
367             .build();
368     assertThat(dataDownloadFileGroupStats).isEqualTo(staleGroupExpired);
369 
370     logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
371     // 1084 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED;
372     // Called once for every released lease.
373     verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1084));
374 
375     logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
376     // 1051 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
377     // It's logged once every time mobileDataDownload.maintenance() is called and three times in the
378     // ExpirationHandler, once when the file metadata is deleted, once when the lease is released
379     // and once when the temporary local copy of the shared file is deleted.
380     verify(mockLogger, times(5)).log(logDataCaptor.capture(), /* eventCode= */ eq(1051));
381     logData = logDataCaptor.getAllValues();
382     assertThat(logData).hasSize(5);
383 
384     Void metadafileDeleted = null;
385     Void fileReleased = null;
386     Void fileDeleted = null;
387   }
388 
389   @Test
deletesExpiredGroups()390   public void deletesExpiredGroups() throws Exception {
391     mobileDataDownload = builderForTest().build();
392     Uri androidUri =
393         BlobUri.builder(context).setBlobParameters(FILE_ANDROID_SHARING_CHECKSUM_1).build();
394     assertThat(fileStorage.exists(androidUri)).isFalse();
395 
396     // Download file group with stale lifetime +2 days.
397     DataFileGroup fileGroup =
398         TestFileGroupPopulator.createDataFileGroup(
399             FILE_GROUP_TO_SHARE_1,
400             context.getPackageName(),
401             new String[] {FILE_ID_1},
402             new int[] {FILE_SIZE_1},
403             new String[] {FILE_CHECKSUM_1},
404             new String[] {FILE_ANDROID_SHARING_CHECKSUM_1},
405             new String[] {FILE_URL_1},
406             DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
407 
408     // It expires in two days.
409     fileGroup = fileGroup.toBuilder().setExpirationDate(MddTestUtil.daysFromNow(2)).build();
410 
411     downloadFileGroup(fileGroup);
412 
413     ClientFileGroup clientFileGroup = verifyDownloadedGroupIsDownloaded(fileGroup, 1);
414 
415     ClientFile clientFile = clientFileGroup.getFileList().get(0);
416     assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_1);
417     Uri uri = Uri.parse(clientFile.getFileUri());
418 
419     // The file is now available in the android shared storage.
420     assertThat(uri).isEqualTo(androidUri);
421     assertThat(fileStorage.exists(uri)).isTrue();
422     assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
423 
424     // Run maintenance tasks and verify that we still own the lease om the shared file.
425     mobileDataDownload.maintenance().get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
426 
427     verifyDownloadedGroupIsDownloaded(fileGroup, 1);
428 
429     assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
430 
431     // Advance time by 3 days, and verify that the group and files can no longer be read
432     // because they expired.
433     MddTestUtil.timeTravel(context, DAYS.toMillis(3));
434     mobileDataDownload.maintenance().get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
435     clientFileGroup =
436         mobileDataDownload
437             .getFileGroup(
438                 GetFileGroupRequest.newBuilder().setGroupName(FILE_GROUP_TO_SHARE_1).build())
439             .get();
440     assertThat(clientFileGroup).isNull();
441 
442     assertThat(blobStoreManager.getLeasedBlobs()).isEmpty();
443 
444     // Verify logging events.
445 
446     ArgumentCaptor<MddLogData> logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
447     // 1049 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
448     verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1049));
449 
450     List<MddLogData> logData = logDataCaptor.getAllValues();
451     assertThat(logData).hasSize(1);
452 
453     DataDownloadFileGroupStats dataDownloadFileGroupStats =
454         logData.get(0).getDataDownloadFileGroupStats();
455     DataDownloadFileGroupStats groupExpired =
456         DataDownloadFileGroupStats.newBuilder()
457             .setFileGroupName(fileGroup.getGroupName())
458             .setFileGroupVersionNumber(fileGroup.getFileGroupVersionNumber())
459             .setBuildId(0)
460             .setVariantId("")
461             .build();
462     assertThat(dataDownloadFileGroupStats).isEqualTo(groupExpired);
463 
464     logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
465     // 1084 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED;
466     // Called once for every released lease.
467     verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1084));
468 
469     logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
470     // 1051 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
471     // It's logged once every time mobileDataDownload.maintenance() is called and three times in the
472     // ExpirationHandler, once when the file metadata is deleted, once when the lease is
473     // released and once when the temporary local copy of the shared file is deleted.
474     verify(mockLogger, times(5)).log(logDataCaptor.capture(), /* eventCode= */ eq(1051));
475     logData = logDataCaptor.getAllValues();
476     assertThat(logData).hasSize(5);
477 
478     Void metadafileDeleted = null;
479     Void fileReleased = null;
480     Void fileDeleted = null;
481   }
482 
483   /**
484    * Returns MDD Builder with common dependencies set -- additional dependencies are added in each
485    * test as needed.
486    */
builderForTest()487   private MobileDataDownloadBuilder builderForTest() {
488     return MobileDataDownloadBuilder.newBuilder()
489         .setContext(context)
490         .setControlExecutor(controlExecutor)
491         .setFileDownloaderSupplier(fileDownloaderSupplier)
492         .setTaskScheduler(Optional.of(mockTaskScheduler))
493         .setDeltaDecoderOptional(Optional.absent())
494         .setFileStorage(fileStorage)
495         .setNetworkUsageMonitor(mockNetworkUsageMonitor)
496         .setDownloadMonitorOptional(Optional.of(mockDownloadProgressMonitor))
497         .setLoggerOptional(Optional.of(mockLogger))
498         .setFlagsOptional(Optional.of(flags));
499   }
500 }
501