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