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.finalization; 18 19 import static android.app.admin.DeviceAdminInfo.HEADLESS_DEVICE_OWNER_MODE_AFFILIATED; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 21 import static android.app.admin.DevicePolicyManager.STATE_USER_PROFILE_COMPLETE; 22 import static android.app.admin.DevicePolicyManager.STATE_USER_PROFILE_FINALIZED; 23 import static android.app.admin.DevicePolicyManager.STATE_USER_SETUP_COMPLETE; 24 import static android.app.admin.DevicePolicyManager.STATE_USER_SETUP_FINALIZED; 25 import static android.app.admin.DevicePolicyManager.STATE_USER_UNMANAGED; 26 import static android.content.Context.DEVICE_POLICY_SERVICE; 27 28 import static com.android.internal.util.Preconditions.checkNotNull; 29 30 import android.app.admin.DevicePolicyManager; 31 import android.app.admin.flags.Flags; 32 import android.content.Context; 33 import android.os.UserHandle; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 import com.android.managedprovisioning.common.ProvisionLogger; 37 import com.android.managedprovisioning.common.SettingsFacade; 38 import com.android.managedprovisioning.common.Utils; 39 import com.android.managedprovisioning.model.ProvisioningParams; 40 41 /** 42 * Helper class to handle the user provisioning states. 43 * 44 * <p>This class calls interacts with {@link DevicePolicyManager} to handle the setting of 45 * user provisioning states at the end of provisioning.</p> 46 */ 47 @VisibleForTesting 48 public class UserProvisioningStateHelper { 49 private final Context mContext; 50 private final DevicePolicyManager mDevicePolicyManager; 51 private final Utils mUtils; 52 private final SettingsFacade mSettingsFacade; 53 private final int mMyUserId; 54 UserProvisioningStateHelper(Context context)55 public UserProvisioningStateHelper(Context context) { 56 this(context, new Utils(), new SettingsFacade(), UserHandle.myUserId()); 57 } 58 59 @VisibleForTesting UserProvisioningStateHelper(Context context, Utils utils, SettingsFacade settingsFacade, int myUserId)60 UserProvisioningStateHelper(Context context, 61 Utils utils, 62 SettingsFacade settingsFacade, 63 int myUserId) { 64 mContext = checkNotNull(context); 65 mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService( 66 DEVICE_POLICY_SERVICE); 67 mUtils = checkNotNull(utils); 68 mSettingsFacade = checkNotNull(settingsFacade); 69 mMyUserId = myUserId; 70 } 71 72 /** 73 * Set the current users userProvisioningState depending on the following factors: 74 * <ul> 75 * <li>We're setting up a managed-profile - need to set state on two users.</li> 76 * <li>User-setup has previously been completed or not - skip states relating to 77 * communicating with setup-wizard.</li> 78 * <li>DPC requested we skip the rest of setup-wizard.</li> 79 * </ul> 80 * 81 * @param params configuration for current provisioning attempt 82 */ 83 @VisibleForTesting markUserProvisioningStateInitiallyDone(ProvisioningParams params)84 public void markUserProvisioningStateInitiallyDone(ProvisioningParams params) { 85 final boolean userSetupCompleted = mSettingsFacade.isUserSetupCompleted(mContext); 86 87 int managedProfileUserId = UserHandle.USER_NULL; 88 89 // new provisioning state for current user, if non-null 90 Integer newState = null; 91 // New provisioning state for managed-profile of current user, if non-null. 92 Integer newProfileState = null; 93 94 if (params.provisioningAction.equals(ACTION_PROVISION_MANAGED_PROFILE)) { 95 // Managed profiles are a special case as two users are involved. 96 managedProfileUserId = mUtils.getManagedProfile(mContext).getIdentifier(); 97 if (userSetupCompleted) { 98 // SUW on current user is complete, so nothing much to do beyond indicating we're 99 // all done. 100 if (!isUserProvisioningStateProfileFinalized()) { 101 newState = STATE_USER_PROFILE_FINALIZED; 102 } 103 newProfileState = STATE_USER_SETUP_FINALIZED; 104 } else { 105 // We're still in SUW, so indicate that a managed-profile was setup on current user, 106 // and that we're awaiting finalization on both. 107 newState = STATE_USER_PROFILE_COMPLETE; 108 newProfileState = STATE_USER_SETUP_COMPLETE; 109 } 110 } else if (userSetupCompleted) { 111 if (params.allowProvisioningAfterUserSetupComplete) { 112 ProvisionLogger.logw("Provisioning after user setup complete is allowed, " 113 + "updating provisioning state."); 114 newState = STATE_USER_SETUP_COMPLETE; 115 } else { 116 // User setup was previously completed this is an unexpected case. 117 ProvisionLogger.logw("user_setup_complete set, but provisioning was started"); 118 } 119 } else { 120 newState = STATE_USER_SETUP_COMPLETE; 121 } 122 123 if (newState != null) { 124 setUserProvisioningState(newState, mMyUserId); 125 maybeSetHeadlessSystemUserProvisioningState(params, newState); 126 } 127 if (newProfileState != null) { 128 setUserProvisioningState(newProfileState, managedProfileUserId); 129 } 130 } 131 132 /** 133 * Finalize the current user's userProvisioningState depending on the following factors: 134 * <ul> 135 * <li>We're setting up a managed-profile - need to set state on two users.</li> 136 * </ul> 137 * 138 * @param params configuration for current provisioning attempt - if null (because 139 * ManagedProvisioning wasn't used for first phase of provisioning) aassumes we 140 * can just mark current user as being in finalized provisioning state 141 */ 142 @VisibleForTesting markUserProvisioningStateFinalized(ProvisioningParams params)143 public void markUserProvisioningStateFinalized(ProvisioningParams params) { 144 if (params.provisioningAction.equals(ACTION_PROVISION_MANAGED_PROFILE)) { 145 // Managed profiles are a special case as two users are involved. 146 final int managedProfileUserId = mUtils.getManagedProfile(mContext).getIdentifier(); 147 setUserProvisioningState(STATE_USER_SETUP_FINALIZED, managedProfileUserId); 148 setUserProvisioningState(STATE_USER_PROFILE_FINALIZED, mMyUserId); 149 } else { 150 setUserProvisioningState(STATE_USER_SETUP_FINALIZED, mMyUserId); 151 maybeSetHeadlessSystemUserProvisioningState(params, STATE_USER_SETUP_FINALIZED); 152 } 153 } 154 155 /** 156 * Returns whether the calling user's provision state is unmanaged, finanalized or 157 * user profile finalized. 158 */ 159 @VisibleForTesting isStateUnmanagedOrFinalized()160 public boolean isStateUnmanagedOrFinalized() { 161 final int currentState = mDevicePolicyManager.getUserProvisioningState(); 162 return currentState == STATE_USER_UNMANAGED 163 || currentState == STATE_USER_SETUP_FINALIZED 164 || currentState == STATE_USER_PROFILE_FINALIZED; 165 } 166 167 /** 168 * Resets the provisioning state for {@link UserHandle#USER_SYSTEM} to {@link 169 * DevicePolicyManager#STATE_USER_UNMANAGED}. 170 */ resetPrimaryUserProvisioningState()171 public void resetPrimaryUserProvisioningState() { 172 setUserProvisioningState(STATE_USER_UNMANAGED, UserHandle.USER_SYSTEM); 173 } 174 isUserProvisioningStateProfileFinalized()175 private boolean isUserProvisioningStateProfileFinalized() { 176 final int currentState = mDevicePolicyManager.getUserProvisioningState(); 177 return currentState == STATE_USER_PROFILE_FINALIZED; 178 } 179 setUserProvisioningState(int state, int userId)180 private void setUserProvisioningState(int state, int userId) { 181 ProvisionLogger.logi("Setting userProvisioningState for user " + userId + " to: " + state); 182 mDevicePolicyManager.setUserProvisioningState(state, userId); 183 } 184 maybeSetHeadlessSystemUserProvisioningState(ProvisioningParams params, int newState)185 private void maybeSetHeadlessSystemUserProvisioningState(ProvisioningParams params, int newState) { 186 if (params.provisioningAction.equals(ACTION_PROVISION_MANAGED_PROFILE)) { 187 return; // No special headless logic for managed profiles 188 } 189 if (mUtils.isHeadlessSystemUserMode() 190 && (!Flags.headlessDeviceOwnerProvisioningFixEnabled() 191 || mDevicePolicyManager.getHeadlessDeviceOwnerMode() 192 == HEADLESS_DEVICE_OWNER_MODE_AFFILIATED) 193 && mMyUserId != UserHandle.USER_SYSTEM) { 194 // For affiliated DO, headless system user's DO has to be set on system user and 195 // therefore system user has to be marked the same as the calling user. 196 setUserProvisioningState(newState, UserHandle.USER_SYSTEM); 197 } 198 } 199 } 200