1 /*
2  * Copyright (C) 2021 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.common;
18 
19 import static android.app.admin.DevicePolicyManager.ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER;
20 import static android.app.admin.DevicePolicyManager.EXTRA_FORCE_UPDATE_ROLE_HOLDER;
21 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TRIGGER;
22 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_UNSPECIFIED;
23 
24 import static java.util.Objects.requireNonNull;
25 
26 import android.annotation.Nullable;
27 import android.app.admin.DevicePolicyManager;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.text.TextUtils;
31 
32 import com.android.managedprovisioning.model.ProvisioningParams;
33 import com.android.managedprovisioning.provisioning.Constants;
34 
35 import com.google.android.setupcompat.util.WizardManagerHelper;
36 
37 /**
38  * Helper class for logic related to device management role holder updater launching.
39  */
40 public class DeviceManagementRoleHolderUpdaterHelper {
41 
42     private final String mRoleHolderUpdaterPackageName;
43     private final String mRoleHolderPackageName;
44     private final PackageInstallChecker mPackageInstallChecker;
45     private final IntentResolverChecker mIntentResolverChecker;
46     private final FeatureFlagChecker mFeatureFlagChecker;
47 
DeviceManagementRoleHolderUpdaterHelper( @ullable String roleHolderUpdaterPackageName, @Nullable String roleHolderPackageName, PackageInstallChecker packageInstallChecker, IntentResolverChecker intentResolverChecker, FeatureFlagChecker featureFlagChecker)48     public DeviceManagementRoleHolderUpdaterHelper(
49             @Nullable String roleHolderUpdaterPackageName,
50             @Nullable String roleHolderPackageName,
51             PackageInstallChecker packageInstallChecker,
52             IntentResolverChecker intentResolverChecker,
53             FeatureFlagChecker featureFlagChecker) {
54         mRoleHolderUpdaterPackageName = roleHolderUpdaterPackageName;
55         mRoleHolderPackageName = roleHolderPackageName;
56         mPackageInstallChecker = requireNonNull(packageInstallChecker);
57         mIntentResolverChecker = requireNonNull(intentResolverChecker);
58         mFeatureFlagChecker = requireNonNull(featureFlagChecker);
59     }
60 
61     /**
62      * Returns whether the device management role holder updater should be started.
63      */
shouldStartRoleHolderUpdater(Context context, Intent managedProvisioningIntent, ProvisioningParams params)64     public boolean shouldStartRoleHolderUpdater(Context context, Intent managedProvisioningIntent,
65             ProvisioningParams params) {
66         if (!Constants.isRoleHolderProvisioningAllowedForAction(
67                 managedProvisioningIntent.getAction())) {
68             ProvisionLogger.logi("Not starting role holder updater, because this provisioning "
69                     + "action is unsupported: " + managedProvisioningIntent.getAction());
70             return false;
71         }
72         if (shouldPlatformDownloadRoleHolder(managedProvisioningIntent, params)) {
73             ProvisionLogger.logi("Not starting role holder updater, because the platform will "
74                     + "download the role holder instead.");
75             return false;
76         }
77         if (!mFeatureFlagChecker.canDelegateProvisioningToRoleHolder()) {
78             ProvisionLogger.logi("Not starting role holder updater, because the feature flag "
79                     + "is turned off.");
80             return false;
81         }
82         if (TextUtils.isEmpty(mRoleHolderPackageName)) {
83             ProvisionLogger.logi("Not starting role holder updater, because the role holder "
84                     + "package name is null or empty.");
85             return false;
86         }
87         if (TextUtils.isEmpty(mRoleHolderUpdaterPackageName)) {
88             ProvisionLogger.logi("Not starting role holder updater, because the role holder "
89                     + "updater package name is null or empty.");
90             return false;
91         }
92         if (!mPackageInstallChecker.isPackageInstalled(mRoleHolderUpdaterPackageName)) {
93             ProvisionLogger.logi("Not starting role holder updater, because the role holder "
94                     + "updater is not installed.");
95             return false;
96         }
97         Intent roleHolderUpdaterIntent = createRoleHolderUpdaterIntent(
98                 managedProvisioningIntent,
99                 managedProvisioningIntent.getIntExtra(
100                         EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_UNSPECIFIED),
101                 /* isRoleHolderRequestedUpdate= */ false);
102         if (!mIntentResolverChecker.canResolveIntent(roleHolderUpdaterIntent)) {
103             ProvisionLogger.logi("Not starting role holder updater, because the role holder "
104                     + "updater does not resolve the intent " + roleHolderUpdaterIntent);
105             return false;
106         }
107         return true;
108     }
109 
110 
111     /**
112      * Returns {@code true} if the platform should download the role holder, instead of the
113      * role holder updater.
114      *
115      * @see #shouldStartRoleHolderUpdater(Context, Intent, ProvisioningParams)
116      */
shouldPlatformDownloadRoleHolder( Intent managedProvisioningIntent, ProvisioningParams params)117     public boolean shouldPlatformDownloadRoleHolder(
118             Intent managedProvisioningIntent, ProvisioningParams params) {
119         if (params.roleHolderDownloadInfo == null) {
120             ProvisionLogger.logi("Not performing platform-side role holder download, because "
121                     + "there is no role holder download info supplied.");
122             return false;
123         }
124         if (!DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE.equals(
125                 managedProvisioningIntent.getAction())) {
126             ProvisionLogger.logi("Not performing platform-side role holder download, because "
127                     + "this provisioning action is unsupported: "
128                     + managedProvisioningIntent.getAction());
129             return false;
130         }
131         if (!mFeatureFlagChecker.canDelegateProvisioningToRoleHolder()) {
132             ProvisionLogger.logi("Not performing platform-side role holder download, because "
133                     + "the feature flag is turned off.");
134             return false;
135         }
136         if (TextUtils.isEmpty(mRoleHolderPackageName)) {
137             ProvisionLogger.logi("Not performing platform-side role holder download, because "
138                     + "the role holder package name is null or empty.");
139             return false;
140         }
141         return true;
142     }
143 
144     /**
145      * Creates an intent to be used to launch the role holder updater.
146      */
createRoleHolderUpdaterIntent( @ullable Intent parentActivityIntent, int provisioningTrigger, boolean isRoleHolderRequestedUpdate)147     public Intent createRoleHolderUpdaterIntent(
148             @Nullable Intent parentActivityIntent,
149             int provisioningTrigger,
150             boolean isRoleHolderRequestedUpdate) {
151         if (TextUtils.isEmpty(mRoleHolderUpdaterPackageName)) {
152             throw new IllegalStateException("Role holder updater package name is null or empty.");
153         }
154         Intent intent = new Intent(ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER)
155                 .setPackage(mRoleHolderUpdaterPackageName)
156                 .putExtra(EXTRA_PROVISIONING_TRIGGER, provisioningTrigger)
157                 .putExtra(EXTRA_FORCE_UPDATE_ROLE_HOLDER, isRoleHolderRequestedUpdate);
158         if (parentActivityIntent != null) {
159             WizardManagerHelper.copyWizardManagerExtras(parentActivityIntent, intent);
160         }
161         return intent;
162     }
163 
isRoleHolderUpdaterDefined()164     public boolean isRoleHolderUpdaterDefined() {
165         return !TextUtils.isEmpty(mRoleHolderUpdaterPackageName);
166     }
167 }
168