1 /* 2 * Copyright (C) 2019 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_PROVISION_MANAGED_PROFILE; 20 21 import static com.android.managedprovisioning.provisioning.Constants.EXTRA_PROVISIONING_COLOR_PALETTE; 22 23 import android.app.Activity; 24 import android.app.admin.DevicePolicyManager; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.os.UserHandle; 28 29 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 30 import com.android.managedprovisioning.model.ProvisioningParams; 31 32 import com.google.android.setupcompat.util.WizardManagerHelper; 33 34 import java.util.HashMap; 35 import java.util.function.BiConsumer; 36 37 /** 38 * Class containing utility methods for starting up a DPC during Setup Wizard. 39 */ 40 public class PolicyComplianceUtils { 41 42 /** 43 * Returns whether the DPC handles the policy compliance activity on the managed user. 44 */ isPolicyComplianceActivityResolvableForManagedUser( Context context, ProvisioningParams params, Utils utils)45 public boolean isPolicyComplianceActivityResolvableForManagedUser( 46 Context context, ProvisioningParams params, Utils utils) { 47 UserHandle userHandle = getPolicyComplianceUserHandle(context, params, utils); 48 return getPolicyComplianceIntentIfResolvable(context, params, utils, userHandle) != null; 49 } 50 51 /** 52 * Returns whether the DPC handles the policy compliance activity on a given user. 53 */ isPolicyComplianceActivityResolvableForUser( Context context, ProvisioningParams params, Utils utils, UserHandle userHandle)54 public boolean isPolicyComplianceActivityResolvableForUser( 55 Context context, ProvisioningParams params, Utils utils, UserHandle userHandle) { 56 return getPolicyComplianceIntentIfResolvable(context, params, utils, userHandle) != null; 57 } 58 59 /** 60 * Starts the policy compliance activity if it can be resolved, and returns whether the 61 * activity was started. 62 */ startPolicyComplianceActivityForResultIfResolved(Activity parentActivity, ProvisioningParams params, int requestCode, Utils utils, ProvisioningAnalyticsTracker provisioningAnalyticsTracker, TransitionHelper transitionHelper)63 public boolean startPolicyComplianceActivityForResultIfResolved(Activity parentActivity, 64 ProvisioningParams params, int requestCode, Utils utils, 65 ProvisioningAnalyticsTracker provisioningAnalyticsTracker, 66 TransitionHelper transitionHelper) { 67 return startPolicyComplianceActivityIfResolvedInternal(parentActivity, params, utils, 68 provisioningAnalyticsTracker, (Intent intent, UserHandle userHandle) -> { 69 if (parentActivity.getIntent() != null) { 70 WizardManagerHelper.copyWizardManagerExtras( 71 parentActivity.getIntent(), intent); 72 } 73 transitionHelper.startActivityForResultAsUserWithTransition( 74 parentActivity, intent, requestCode, userHandle); 75 }); 76 } 77 78 /** 79 * Starts the policy compliance activity if it can be resolved, and returns whether the 80 * activity was started. 81 */ 82 public boolean startPolicyComplianceActivityIfResolved(Context context, 83 ProvisioningParams params, Utils utils, 84 ProvisioningAnalyticsTracker provisioningAnalyticsTracker) { 85 return startPolicyComplianceActivityIfResolvedInternal( 86 context, 87 params, 88 utils, 89 provisioningAnalyticsTracker, 90 context::startActivityAsUser); 91 } 92 93 private boolean startPolicyComplianceActivityIfResolvedInternal( 94 Context context, ProvisioningParams params, Utils utils, 95 ProvisioningAnalyticsTracker provisioningAnalyticsTracker, 96 BiConsumer<Intent, UserHandle> startActivityFunc) { 97 final UserHandle userHandle = getPolicyComplianceUserHandle(context, params, utils); 98 final Intent policyComplianceIntent = getPolicyComplianceIntentIfResolvable( 99 context, params, utils, userHandle); 100 101 if (policyComplianceIntent != null) { 102 startActivityFunc.accept(policyComplianceIntent, userHandle); 103 ProvisionLogger.logd( 104 "The DPC POLICY_COMPLIANCE handler was launched on user " + userHandle); 105 provisioningAnalyticsTracker.logDpcSetupStarted( 106 context, policyComplianceIntent.getAction()); 107 return true; 108 } 109 110 return false; 111 } 112 113 private Intent getPolicyComplianceIntentIfResolvable(Context context, 114 ProvisioningParams params, Utils utils, UserHandle userHandle) { 115 final Intent policyComplianceIntent = getPolicyComplianceIntent(params, context); 116 final boolean intentResolvable = utils.canResolveIntentAsUser(context, 117 policyComplianceIntent, userHandle.getIdentifier()); 118 // Calling startActivity() from outside of an Activity context requires 119 // the FLAG_ACTIVITY_NEW_TASK flag. 120 if (!(context instanceof Activity)) { 121 policyComplianceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 122 } 123 return intentResolvable ? policyComplianceIntent : null; 124 } 125 126 private Intent getPolicyComplianceIntent( 127 ProvisioningParams params, Context context) { 128 final String adminPackage = params.inferDeviceAdminPackageName(); 129 final Intent policyComplianceIntent = 130 new Intent(DevicePolicyManager.ACTION_ADMIN_POLICY_COMPLIANCE); 131 policyComplianceIntent.putExtra( 132 DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, 133 params.adminExtrasBundle); 134 // TODO(b/192254845): Remove EXTRA_PROVISIONING_COLOR_PALETTE when framework 135 // fix available 136 HashMap<Integer, Integer> colorPaletteMap = 137 new ColorPaletteHelper().createColorPaletteMap( 138 context, 139 new ManagedProvisioningSharedPreferences(context)); 140 policyComplianceIntent.putExtra(EXTRA_PROVISIONING_COLOR_PALETTE, colorPaletteMap); 141 policyComplianceIntent.setPackage(adminPackage); 142 return policyComplianceIntent; 143 } 144 145 private UserHandle getPolicyComplianceUserHandle(Context context, 146 ProvisioningParams params, Utils utils) { 147 return params.provisioningAction.equals(ACTION_PROVISION_MANAGED_PROFILE) 148 ? utils.getManagedProfile(context) 149 : UserHandle.of(UserHandle.myUserId()); 150 } 151 } 152