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 java.nio.charset.StandardCharsets.UTF_8; 19 20 import android.content.Context; 21 import android.net.Uri; 22 import android.util.Log; 23 import com.google.android.libraries.mobiledatadownload.file.SynchronousFileStorage; 24 import com.google.android.libraries.mobiledatadownload.file.common.testing.StreamUtils; 25 import com.google.android.libraries.mobiledatadownload.internal.logging.LogUtil; 26 import com.google.common.base.Preconditions; 27 import com.google.common.util.concurrent.FluentFuture; 28 import com.google.common.util.concurrent.FutureCallback; 29 import com.google.common.util.concurrent.Futures; 30 import com.google.common.util.concurrent.ListenableFuture; 31 import com.google.common.util.concurrent.MoreExecutors; 32 import com.google.mobiledatadownload.ClientConfigProto.ClientFileGroup; 33 import com.google.mobiledatadownload.DownloadConfigProto.DataFileGroup; 34 import com.google.mobiledatadownload.DownloadConfigProto.DownloadConditions.DeviceNetworkPolicy; 35 import java.io.IOException; 36 37 /** 38 * A file group populator that demonstrate the 2-step download. The populator will read the content 39 * from first group and then add the second group to MDD. 40 */ 41 public class TwoStepPopulator implements FileGroupPopulator { 42 private static final String TAG = "TwoStepPopulator"; 43 44 private final Context context; 45 private final SynchronousFileStorage fileStorage; 46 TwoStepPopulator(Context context, SynchronousFileStorage fileStorage)47 public TwoStepPopulator(Context context, SynchronousFileStorage fileStorage) { 48 this.context = context; 49 this.fileStorage = fileStorage; 50 } 51 52 @Override refreshFileGroups(MobileDataDownload mobileDataDownload)53 public ListenableFuture<Void> refreshFileGroups(MobileDataDownload mobileDataDownload) { 54 ListenableFuture<ClientFileGroup> step1Future = 55 mobileDataDownload.getFileGroup( 56 GetFileGroupRequest.newBuilder().setGroupName("step1-file-group").build()); 57 58 return FluentFuture.from(step1Future) 59 .transformAsync( 60 clientFileGroup -> { 61 if (clientFileGroup == null) { 62 return Futures.immediateFuture(null); 63 } 64 65 LogUtil.d("%s: Retrieved step1-file-group from MDD", TAG); 66 67 // Now read the url from the step1.txt 68 Uri fileUri = Uri.parse(clientFileGroup.getFile(0).getFileUri()); 69 String step1Content = null; 70 try { 71 step1Content = new String(StreamUtils.readFileInBytes(fileStorage, fileUri), UTF_8); 72 } catch (IOException e) { 73 LogUtil.e(e, "Fail to read from step1.txt"); 74 } 75 76 // Add a file group where the url is read from step1.txt 77 DataFileGroup step2FileGroup = 78 TestFileGroupPopulator.createDataFileGroup( 79 "step2-file-group", 80 context.getPackageName(), 81 new String[] {"step2_id"}, 82 new int[] {13}, 83 new String[] {""}, 84 new String[] {step1Content}, 85 DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK); 86 87 ListenableFuture<Boolean> addFileGroupFuture = 88 mobileDataDownload.addFileGroup( 89 AddFileGroupRequest.newBuilder().setDataFileGroup(step2FileGroup).build()); 90 Futures.addCallback( 91 addFileGroupFuture, 92 new FutureCallback<Boolean>() { 93 @Override 94 public void onSuccess(Boolean result) { 95 Preconditions.checkState(result.booleanValue()); 96 if (result.booleanValue()) { 97 Log.d(TAG, "Added file group " + step2FileGroup.getGroupName()); 98 } else { 99 Log.d(TAG, "Failed to add file group " + step2FileGroup.getGroupName()); 100 } 101 } 102 103 @Override 104 public void onFailure(Throwable t) { 105 Log.e(TAG, "Failed to add file group", t); 106 } 107 }, 108 MoreExecutors.directExecutor()); 109 return addFileGroupFuture; 110 }, 111 MoreExecutors.directExecutor()) 112 .transform(addFileGroupSucceeded -> null, MoreExecutors.directExecutor()); 113 } 114 } 115