1 /*
2  * Copyright (C) 2023 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 package com.android.server;
17 
18 import android.content.pm.UserInfo;
19 import android.os.UserHandle;
20 import android.os.UserManager;
21 
22 import com.android.server.am.ActivityManagerService;
23 import com.android.server.pm.UserManagerInternal;
24 import com.android.server.utils.Slogf;
25 import com.android.server.utils.TimingsTraceAndSlog;
26 
27 /**
28  * Responsible for creating the communal profile at first boot, if required.
29  */
30 public class CommunalProfileInitializer {
31 
32     private static final String TAG = CommunalProfileInitializer.class.getSimpleName();
33 
34     private UserManagerInternal mUmi;
35     private final ActivityManagerService mAms;
36 
CommunalProfileInitializer(ActivityManagerService ams)37     public CommunalProfileInitializer(ActivityManagerService ams) {
38         mUmi = LocalServices.getService(UserManagerInternal.class);
39         mAms = ams;
40     }
41 
42     /**
43      * Initialize this object and create the Communal Profile if needed.
44      */
init(TimingsTraceAndSlog t)45     public void init(TimingsTraceAndSlog t) {
46         Slogf.i(TAG, "init())");
47 
48         t.traceBegin("createCommunalProfileIfNeeded");
49         createCommunalProfileIfNeeded();
50         t.traceEnd();
51     }
52 
createCommunalProfileIfNeeded()53     private void createCommunalProfileIfNeeded() {
54         final int communalProfile = mUmi.getCommunalProfileId();
55         if (communalProfile != UserHandle.USER_NULL) {
56             Slogf.d(TAG, "Found existing Communal Profile, userId=%d", communalProfile);
57             return;
58         }
59 
60         Slogf.d(TAG, "Creating a new Communal Profile");
61         try {
62             // TODO: b/293860614 - Create Communal Profile string name
63             final UserInfo newProfile = mUmi.createUserEvenWhenDisallowed(
64                     /* name= */ null,
65                     UserManager.USER_TYPE_PROFILE_COMMUNAL,
66                     /* flags= */ 0, /* disallowedPackages= */ null, /* token= */ null);
67             Slogf.i(TAG, "Successfully created Communal Profile, userId=%d", newProfile.id);
68         } catch (UserManager.CheckedUserOperationException e) {
69             Slogf.wtf(TAG, "Communal Profile creation failed", e);
70         }
71     }
72 
removeCommunalProfileIfPresent()73     static void removeCommunalProfileIfPresent() {
74         final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
75         final int communalProfile = umi.getCommunalProfileId();
76         if (communalProfile == UserHandle.USER_NULL) {
77             return;
78         }
79         Slogf.d(TAG, "Removing existing Communal Profile, userId=%d", communalProfile);
80         final boolean removeSucceeded = umi.removeUserEvenWhenDisallowed(communalProfile);
81         if (!removeSucceeded) {
82             Slogf.e(TAG, "Failed to remove Communal Profile, userId=%d", communalProfile);
83         }
84     }
85 
86 }
87