• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016, The Android Open Source Project
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 
17 package com.android.managedprovisioning.task;
18 
19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
20 
21 import static com.android.managedprovisioning.task.DownloadPackageTask.ERROR_DOWNLOAD_FAILED;
22 import static com.android.managedprovisioning.task.DownloadPackageTask.ERROR_OTHER;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.mockito.Matchers.any;
26 import static org.mockito.Matchers.nullable;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.verifyNoMoreInteractions;
31 import static org.mockito.Mockito.when;
32 
33 import android.app.DownloadManager;
34 import android.app.DownloadManager.Query;
35 import android.app.DownloadManager.Request;
36 import android.content.BroadcastReceiver;
37 import android.content.Context;
38 import android.content.Intent;
39 import android.content.IntentFilter;
40 import android.database.MatrixCursor;
41 import android.os.Handler;
42 import android.os.Looper;
43 
44 import androidx.test.filters.FlakyTest;
45 import androidx.test.filters.SmallTest;
46 
47 import com.android.managedprovisioning.analytics.MetricsWriter;
48 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
49 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
50 import com.android.managedprovisioning.common.Utils;
51 import com.android.managedprovisioning.model.PackageDownloadInfo;
52 import com.android.managedprovisioning.model.ProvisioningParams;
53 
54 import org.junit.Before;
55 import org.junit.Test;
56 import org.mockito.ArgumentCaptor;
57 import org.mockito.Mock;
58 import org.mockito.MockitoAnnotations;
59 
60 @SmallTest
61 @FlakyTest // TODO: http://b/34117742
62 public class DownloadPackageTaskTest {
63     @Mock private Context mContext;
64     @Mock private AbstractProvisioningTask.Callback mCallback;
65     @Mock private DownloadManager mDownloadManager;
66     @Mock private Utils mUtils;
67 
68     private static final String TEST_PACKAGE_NAME = "sample.package.name";
69     private static final String TEST_PACKAGE_LOCATION = "http://www.some.uri.com";
70     private static final String TEST_LOCAL_FILENAME = "/local/filename";
71     private static final int TEST_USER_ID = 123;
72     private static final byte[] TEST_SIGNATURE = new byte[] {'a', 'b', 'c', 'd'};
73 
74     private static final long TEST_DOWNLOAD_ID = 1234;
75     private static final int PACKAGE_VERSION = 43;
76     private static final PackageDownloadInfo TEST_DOWNLOAD_INFO = new PackageDownloadInfo.Builder()
77             .setLocation(TEST_PACKAGE_LOCATION)
78             .setSignatureChecksum(TEST_SIGNATURE)
79             .setMinVersion(PACKAGE_VERSION)
80             .build();
81     private static final ProvisioningParams PARAMS = new ProvisioningParams.Builder()
82             .setDeviceAdminPackageName(TEST_PACKAGE_NAME)
83             .setProvisioningAction(ACTION_PROVISION_MANAGED_DEVICE)
84             .setDeviceAdminDownloadInfo(TEST_DOWNLOAD_INFO)
85             .build();
86 
87     private DownloadPackageTask mTask;
88 
89     @Before
setUp()90     public void setUp() throws Exception {
91         MockitoAnnotations.initMocks(this);
92 
93         when(mContext.getSystemService(Context.DOWNLOAD_SERVICE)).thenReturn(mDownloadManager);
94         when(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME, PACKAGE_VERSION, mContext))
95                 .thenReturn(true);
96 
97         mTask = new DownloadPackageTask(
98                 mUtils,
99                 mContext,
100                 PARAMS,
101                 mCallback,
102                 mock(ProvisioningAnalyticsTracker.class));
103     }
104 
105     @Test
testAlreadyInstalled()106     public void testAlreadyInstalled() throws Exception {
107         // GIVEN the package is already installed, with the right version
108         when(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME, PACKAGE_VERSION, mContext))
109                 .thenReturn(false);
110 
111         // WHEN running the download package task
112         runTask();
113 
114         // THEN we get a success callback directly
115         verifyOnTaskFinished(null);
116         verifyNoMoreInteractions(mCallback);
117     }
118 
119     @Test
testNotConnected()120     public void testNotConnected() throws Exception {
121         // GIVEN we're not connected to a network
122         doReturn(false).when(mUtils).isConnectedToNetwork(mContext);
123 
124         // WHEN running the download package task
125         runTask();
126 
127         // THEN we get an error callback
128         verify(mCallback).onError(mTask, ERROR_OTHER);
129         verifyNoMoreInteractions(mCallback);
130     }
131 
132     @Test
testDownloadFailed()133     public void testDownloadFailed() throws Exception {
134         // GIVEN the download succeeds
135         mockSuccessfulDownload(DownloadManager.STATUS_FAILED);
136 
137         // WHEN running the download package task
138         runTask();
139 
140         // THEN a download receiver was registered
141         BroadcastReceiver receiver = verifyDownloadReceiver();
142 
143         // WHEN invoking download complete
144         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
145 
146         // THEN we get a success callback
147         verify(mCallback).onError(mTask, ERROR_DOWNLOAD_FAILED);
148         verifyNoMoreInteractions(mCallback);
149     }
150 
151     @Test
testDownloadSucceeded()152     public void testDownloadSucceeded() throws Exception {
153         // GIVEN the download succeeds
154         mockSuccessfulDownload(DownloadManager.STATUS_SUCCESSFUL);
155 
156         // WHEN running the download package task
157         runTask();
158 
159         // THEN a download receiver was registered
160         BroadcastReceiver receiver = verifyDownloadReceiver();
161 
162         // WHEN invoking download complete
163         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
164 
165         // THEN we get a success callback
166         verifyOnTaskFinished(TEST_LOCAL_FILENAME);
167         verifyNoMoreInteractions(mCallback);
168     }
169 
170     /** Test that it works fine even if DownloadManager sends the broadcast twice */
171     @Test
testSendBroadcastTwice()172     public void testSendBroadcastTwice() throws Exception {
173         // GIVEN the download succeeds
174         mockSuccessfulDownload(DownloadManager.STATUS_SUCCESSFUL);
175 
176         // WHEN running the download package task
177         runTask();
178 
179         // THEN a download receiver was registered
180         BroadcastReceiver receiver = verifyDownloadReceiver();
181 
182         // WHEN invoking download complete twice
183         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
184         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
185 
186         // THEN we still get only one success callback
187         verifyOnTaskFinished(TEST_LOCAL_FILENAME);
188         verifyNoMoreInteractions(mCallback);
189     }
190 
mockSuccessfulDownload(int downloadStatus)191     private void mockSuccessfulDownload(int downloadStatus) {
192         doReturn(true).when(mUtils).isConnectedToNetwork(any(Context.class));
193         when(mDownloadManager.enqueue(any(Request.class))).thenReturn(TEST_DOWNLOAD_ID);
194         MatrixCursor cursor = new MatrixCursor(new String[]{
195                 DownloadManager.COLUMN_STATUS,
196                 DownloadManager.COLUMN_LOCAL_FILENAME});
197         cursor.addRow(new Object[]{downloadStatus, TEST_LOCAL_FILENAME});
198         when(mDownloadManager.query(any(Query.class))).thenReturn(cursor);
199     }
200 
verifyDownloadReceiver()201     private BroadcastReceiver verifyDownloadReceiver() {
202         verify(mDownloadManager).setAccessFilename(true);
203         ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
204                 BroadcastReceiver.class);
205         ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(
206                 IntentFilter.class);
207         verify(mContext).registerReceiver(
208                 receiverCaptor.capture(),
209                 filterCaptor.capture(),
210                 nullable(String.class),
211                 any(Handler.class));
212         assertEquals(filterCaptor.getValue().getAction(0),
213                 DownloadManager.ACTION_DOWNLOAD_COMPLETE);
214         return receiverCaptor.getValue();
215     }
216 
verifyOnTaskFinished(String location)217     private void verifyOnTaskFinished(String location) {
218         verify(mCallback).onSuccess(mTask);
219         assertEquals(location, mTask.getDownloadedPackageLocation());
220     }
221 
runTask()222     private void runTask() {
223         if (Looper.myLooper() == null) {
224             Looper.prepare();
225         }
226         mTask.run(TEST_USER_ID);
227     }
228 }
229