1 /* 2 * Copyright 2018, 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.finalization; 18 19 import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISIONING_SUCCESSFUL; 21 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; 22 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_UNSPECIFIED; 23 24 import static com.android.managedprovisioning.model.ProvisioningParams.FLOW_TYPE_ADMIN_INTEGRATED; 25 import static com.android.managedprovisioning.provisioning.Constants.EXTRA_PROVISIONING_COLOR_PALETTE; 26 27 import android.annotation.NonNull; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.os.UserHandle; 31 32 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 33 import com.android.managedprovisioning.common.ColorPaletteHelper; 34 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 35 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences; 36 import com.android.managedprovisioning.common.PolicyComplianceUtils; 37 import com.android.managedprovisioning.common.ProvisionLogger; 38 import com.android.managedprovisioning.common.SettingsFacade; 39 import com.android.managedprovisioning.common.Utils; 40 import com.android.managedprovisioning.model.ProvisioningParams; 41 42 import java.util.HashMap; 43 44 /** 45 * Helper class for creating intents in finalization controller. 46 */ 47 class ProvisioningIntentProvider { maybeLaunchDpc(ProvisioningParams params, int userId, Utils utils, Context context, ProvisioningAnalyticsTracker provisioningAnalyticsTracker, PolicyComplianceUtils policyComplianceUtils, SettingsFacade settingsFacade)48 void maybeLaunchDpc(ProvisioningParams params, int userId, Utils utils, Context context, 49 ProvisioningAnalyticsTracker provisioningAnalyticsTracker, 50 PolicyComplianceUtils policyComplianceUtils, 51 SettingsFacade settingsFacade) { 52 if (shouldLaunchPolicyCompliance( 53 context, settingsFacade, params, policyComplianceUtils, utils, userId)) { 54 launchPolicyComplianceDpcHandler( 55 context, params, utils, provisioningAnalyticsTracker, policyComplianceUtils); 56 } else { 57 launchProvisioningSuccessfulDpcHandler( 58 params, userId, utils, context, provisioningAnalyticsTracker); 59 } 60 } 61 62 // TODO(b/184855881): Make manually-installed-and-started-DPC provisioning use the 63 // policy compliance screen. Then here we will only check if we're doing the admin-integrated 64 // flow. shouldLaunchPolicyCompliance( Context context, SettingsFacade settingsFacade, ProvisioningParams params, PolicyComplianceUtils policyComplianceUtils, Utils utils, int userId)65 private boolean shouldLaunchPolicyCompliance( 66 Context context, SettingsFacade settingsFacade, ProvisioningParams params, 67 PolicyComplianceUtils policyComplianceUtils, Utils utils, int userId) { 68 // If we're performing the admin-integrated flow, we've already validated that 69 // the policy compliance handler exists. 70 if (params.flowType == FLOW_TYPE_ADMIN_INTEGRATED) { 71 return true; 72 } 73 if (!policyComplianceUtils.isPolicyComplianceActivityResolvableForUser( 74 context, params, utils, UserHandle.of(userId))) { 75 return false; 76 } 77 // TODO(b/184933215): Remove logic specific to legacy managed account provisioning 78 if (params.provisioningTrigger != PROVISIONING_TRIGGER_UNSPECIFIED) { 79 return false; 80 } 81 return settingsFacade.isDuringSetupWizard(context); 82 } 83 launchPolicyComplianceDpcHandler( Context context, ProvisioningParams params, Utils utils, ProvisioningAnalyticsTracker provisioningAnalyticsTracker, PolicyComplianceUtils policyComplianceUtils)84 private void launchPolicyComplianceDpcHandler( 85 Context context, ProvisioningParams params, Utils utils, 86 ProvisioningAnalyticsTracker provisioningAnalyticsTracker, 87 PolicyComplianceUtils policyComplianceUtils) { 88 policyComplianceUtils.startPolicyComplianceActivityIfResolved( 89 context, params, utils, provisioningAnalyticsTracker); 90 } 91 launchProvisioningSuccessfulDpcHandler(ProvisioningParams params, int userId, Utils utils, Context context, ProvisioningAnalyticsTracker provisioningAnalyticsTracker)92 private void launchProvisioningSuccessfulDpcHandler(ProvisioningParams params, int userId, 93 Utils utils, Context context, 94 ProvisioningAnalyticsTracker provisioningAnalyticsTracker) { 95 final Intent dpcLaunchIntent = createDpcLaunchIntent(params, context, utils); 96 if (utils.canResolveIntentAsUser(context, dpcLaunchIntent, userId)) { 97 context.startActivityAsUser( 98 createDpcLaunchIntent(params, context, utils), UserHandle.of(userId)); 99 ProvisionLogger.logd("Dpc was launched for user: " + userId); 100 provisioningAnalyticsTracker.logDpcSetupStarted(context, dpcLaunchIntent.getAction()); 101 } 102 } 103 canLaunchDpc(ProvisioningParams params, int userId, Utils utils, Context context)104 boolean canLaunchDpc(ProvisioningParams params, int userId, Utils utils, Context context) { 105 final Intent dpcLaunchIntent = createDpcLaunchIntent(params, context, utils); 106 return utils.canResolveIntentAsUser(context, dpcLaunchIntent, userId); 107 } 108 createProvisioningCompleteIntent( @onNull ProvisioningParams params, int userId, Utils utils, Context context)109 Intent createProvisioningCompleteIntent( 110 @NonNull ProvisioningParams params, int userId, Utils utils, Context context) { 111 Intent intent = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE); 112 try { 113 intent.setComponent(params.inferDeviceAdminComponentName(utils, context, userId)); 114 } catch (IllegalProvisioningArgumentException e) { 115 ProvisionLogger.loge("Failed to infer the device admin component name", e); 116 return null; 117 } 118 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND); 119 addExtrasToIntent(intent, params, context); 120 return intent; 121 } 122 createDpcLaunchIntent( @onNull ProvisioningParams params, Context context, Utils utils)123 private Intent createDpcLaunchIntent( 124 @NonNull ProvisioningParams params, Context context, Utils utils) { 125 Intent intent = new Intent(ACTION_PROVISIONING_SUCCESSFUL); 126 final String packageName = params.inferDeviceAdminPackageName(); 127 if (packageName == null) { 128 ProvisionLogger.loge("Device admin package name is null"); 129 return null; 130 } 131 intent.setPackage(packageName); 132 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 133 addExtrasToIntent(intent, params, context); 134 return intent; 135 } 136 addExtrasToIntent(Intent intent, ProvisioningParams params, Context context)137 private void addExtrasToIntent(Intent intent, ProvisioningParams params, 138 Context context) { 139 intent.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, params.adminExtrasBundle); 140 // TODO(b/192254845): Remove EXTRA_PROVISIONING_COLOR_PALETTE when framework 141 // fix available 142 HashMap<Integer, Integer> colorPaletteMap = 143 new ColorPaletteHelper().createColorPaletteMap( 144 context, 145 new ManagedProvisioningSharedPreferences(context)); 146 intent.putExtra(EXTRA_PROVISIONING_COLOR_PALETTE, colorPaletteMap); 147 } 148 } 149