release-request-bfd62fea-ae1d-4d0d-80fd-4ff0d407c488-for-git_oc-release-4102265 snap-temp-L40000000074340189

Change-Id: I543c97b1349d5235e85bdb89897410296d7a88be
diff --git a/src/com/android/managedprovisioning/common/Utils.java b/src/com/android/managedprovisioning/common/Utils.java
index 5ce04ba..45219ef 100644
--- a/src/com/android/managedprovisioning/common/Utils.java
+++ b/src/com/android/managedprovisioning/common/Utils.java
@@ -191,22 +191,37 @@
                     + " is not installed. ", e);
         }
 
-        final ComponentName componentName;
+        final ComponentName componentName = findDeviceAdminInPackageInfo(dpcPackageName,
+                dpcComponentName, pi);
+        if (componentName == null) {
+            throw new IllegalProvisioningArgumentException("Cannot find any admin receiver in "
+                    + "package " + dpcPackageName + " with component " + dpcComponentName);
+        }
+        return componentName;
+    }
+
+    /**
+     * If dpcComponentName is not null: dpcPackageName is ignored.
+     * Check that the package of dpcComponentName is installed, that dpcComponentName is a
+     * receiver in this package, and return it. The receiver can be in disabled state.
+     *
+     * Otherwise, try to infer a potential device admin component in this package info.
+     *
+     * @return infered device admin component in package info. Otherwise, null
+     */
+    @Nullable
+    public ComponentName findDeviceAdminInPackageInfo(@NonNull String dpcPackageName,
+            @Nullable ComponentName dpcComponentName, @NonNull PackageInfo pi) {
         if (dpcComponentName != null) {
             if (!isComponentInPackageInfo(dpcComponentName, pi)) {
-                throw new IllegalProvisioningArgumentException("The component " + dpcComponentName
-                        + " cannot be found");
+                ProvisionLogger.logw("The component " + dpcComponentName + " isn't registered in "
+                        + "the apk");
+                return null;
             }
-            componentName = dpcComponentName;
+            return dpcComponentName;
         } else {
-            componentName = findDeviceAdminInPackage(dpcPackageName, pi);
-            if (componentName == null) {
-                throw new IllegalProvisioningArgumentException("Cannot find any admin receiver in "
-                        + "package " + dpcPackageName);
-            }
+            return findDeviceAdminInPackage(dpcPackageName, pi);
         }
-
-        return componentName;
     }
 
     /**
@@ -219,7 +234,7 @@
      * @return admin receiver or null in case of error.
      */
     @Nullable
-    public ComponentName findDeviceAdminInPackage(String packageName, PackageInfo packageInfo) {
+    private ComponentName findDeviceAdminInPackage(String packageName, PackageInfo packageInfo) {
         if (packageInfo == null || !TextUtils.equals(packageInfo.packageName, packageName)) {
             return null;
         }
@@ -228,6 +243,7 @@
         for (ActivityInfo ai : packageInfo.receivers) {
             if (TextUtils.equals(ai.permission, android.Manifest.permission.BIND_DEVICE_ADMIN)) {
                 if (mdmComponentName != null) {
+                    ProvisionLogger.logw("more than 1 device admin component are found");
                     return null;
                 } else {
                     mdmComponentName = new ComponentName(packageName, ai.name);
diff --git a/src/com/android/managedprovisioning/task/VerifyPackageTask.java b/src/com/android/managedprovisioning/task/VerifyPackageTask.java
index b540624..a77f74a 100644
--- a/src/com/android/managedprovisioning/task/VerifyPackageTask.java
+++ b/src/com/android/managedprovisioning/task/VerifyPackageTask.java
@@ -90,8 +90,16 @@
 
         PackageInfo packageInfo = mPackageManager.getPackageArchiveInfo(downloadLocation,
                 PackageManager.GET_SIGNATURES | PackageManager.GET_RECEIVERS);
-        if (mUtils.findDeviceAdminInPackage(mProvisioningParams.inferDeviceAdminPackageName(),
-                packageInfo) == null) {
+        String packageName = mProvisioningParams.inferDeviceAdminPackageName();
+        // Device admin package name can't be null
+        if (packageInfo == null || packageName == null) {
+            ProvisionLogger.loge("Device admin package info or name is null");
+            error(ERROR_DEVICE_ADMIN_MISSING);
+            return;
+        }
+
+        if (mUtils.findDeviceAdminInPackageInfo(packageName,
+                mProvisioningParams.deviceAdminComponentName, packageInfo) == null) {
             error(ERROR_DEVICE_ADMIN_MISSING);
             return;
         }
diff --git a/tests/instrumentation/src/com/android/managedprovisioning/common/UtilsTest.java b/tests/instrumentation/src/com/android/managedprovisioning/common/UtilsTest.java
index 75901dd..7e8d87e 100644
--- a/tests/instrumentation/src/com/android/managedprovisioning/common/UtilsTest.java
+++ b/tests/instrumentation/src/com/android/managedprovisioning/common/UtilsTest.java
@@ -267,38 +267,58 @@
         }
     }
 
-    public void testFindDeviceAdminInPackage_Success() throws Exception {
+    public void testFindDeviceAdminInPackageInfo_Success() throws Exception {
         // GIVEN a package info with one device admin
         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
 
-        // THEN calling findDeviceAdminInPackage returns the correct admin
+        // THEN calling findDeviceAdminInPackageInfo returns the correct admin
         assertEquals(TEST_COMPONENT_NAME,
-                mUtils.findDeviceAdminInPackage(TEST_PACKAGE_NAME_1, packageInfo));
+                mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_1, null, packageInfo));
     }
 
-    public void testFindDeviceAdminInPackage_PackageNameMismatch() throws Exception {
+    public void testFindDeviceAdminInPackageInfo_PackageNameMismatch() throws Exception {
         // GIVEN a package info with one device admin
         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
 
-        // THEN calling findDeviceAdminInPackage with the wrong package name return null
-        assertNull(mUtils.findDeviceAdminInPackage(TEST_PACKAGE_NAME_2, packageInfo));
+        // THEN calling findDeviceAdminInPackageInfo with the wrong package name return null
+        assertNull(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_2, null, packageInfo));
     }
 
-    public void testFindDeviceAdminInPackage_NoAdmin() throws Exception {
+    public void testFindDeviceAdminInPackageInfo_NoAdmin() throws Exception {
         // GIVEN a package info with no device admin
         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1);
 
-        // THEN calling findDeviceAdminInPackage returns null
-        assertNull(mUtils.findDeviceAdminInPackage(TEST_PACKAGE_NAME_1, packageInfo));
+        // THEN calling findDeviceAdminInPackageInfo returns null
+        assertNull(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_1, null, packageInfo));
     }
 
-    public void testFindDeviceAdminInPackage_TwoAdmins() throws Exception {
+    public void testFindDeviceAdminInPackageInfo_TwoAdmins() throws Exception {
         // GIVEN a package info with more than one device admin
         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME,
                 TEST_DEVICE_ADMIN_NAME_2);
 
-        // THEN calling findDeviceAdminInPackage returns null
-        assertNull(mUtils.findDeviceAdminInPackage(TEST_PACKAGE_NAME_1, packageInfo));
+        // THEN calling findDeviceAdminInPackageInfo returns null
+        assertNull(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_1, null, packageInfo));
+    }
+
+    public void testFindDeviceAdminInPackageInfo_TwoAdminsWithComponentName() throws Exception {
+        // GIVEN a package info with more than one device admin
+        PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME,
+                TEST_DEVICE_ADMIN_NAME_2);
+
+        // THEN calling findDeviceAdminInPackageInfo return component 1
+        assertEquals(TEST_COMPONENT_NAME, mUtils.findDeviceAdminInPackageInfo(
+                TEST_PACKAGE_NAME_1, TEST_COMPONENT_NAME, packageInfo));
+    }
+
+
+    public void testFindDeviceAdminInPackageInfo_InvalidComponentName() throws Exception {
+        // GIVEN a package info with component 1
+        PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
+
+        // THEN calling findDeviceAdminInPackageInfo with component 2 returns null
+        assertNull(mUtils.findDeviceAdminInPackageInfo(
+                TEST_PACKAGE_NAME_1, TEST_COMPONENT_NAME_2, packageInfo));
     }
 
     public void testComputeHashOfByteArray() {
diff --git a/tests/instrumentation/src/com/android/managedprovisioning/task/VerifyPackageTaskTest.java b/tests/instrumentation/src/com/android/managedprovisioning/task/VerifyPackageTaskTest.java
index 826eb91..09cd332 100644
--- a/tests/instrumentation/src/com/android/managedprovisioning/task/VerifyPackageTaskTest.java
+++ b/tests/instrumentation/src/com/android/managedprovisioning/task/VerifyPackageTaskTest.java
@@ -85,7 +85,7 @@
 
         when(mDownloadPackageTask.getDownloadedPackageLocation()).thenReturn(TEST_LOCAL_FILENAME);
 
-        when(mUtils.findDeviceAdminInPackage(TEST_PACKAGE_NAME, mPackageInfo))
+        when(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME, null, mPackageInfo))
                 .thenReturn(new ComponentName(TEST_PACKAGE_NAME, TEST_ADMIN_NAME));
     }
 
@@ -105,7 +105,8 @@
     @Test
     public void testMissingDeviceAdminComponent() {
         // GIVEN that the device admin component cannot be found
-        when(mUtils.findDeviceAdminInPackage(TEST_PACKAGE_NAME, mPackageInfo)).thenReturn(null);
+        when(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME, null, mPackageInfo))
+                .thenReturn(null);
 
         // WHEN running the VerifyPackageTask
         runWithDownloadInfo(TEST_PACKAGE_CHECKSUM_HASH, EMPTY_BYTE_ARRAY, false);