• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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