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