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