• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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.settings.testutils.shadow;
18 
19 import android.annotation.UserIdInt;
20 import android.content.pm.UserInfo;
21 import android.os.Bundle;
22 import android.os.UserHandle;
23 import android.os.UserManager;
24 import android.os.UserManager.EnforcingUser;
25 
26 import com.google.android.collect.Maps;
27 
28 import org.robolectric.RuntimeEnvironment;
29 import org.robolectric.annotation.Implementation;
30 import org.robolectric.annotation.Implements;
31 import org.robolectric.annotation.Resetter;
32 import org.robolectric.shadow.api.Shadow;
33 
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Set;
41 
42 @Implements(value = UserManager.class)
43 public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
44 
45     private static boolean sIsSupportsMultipleUsers;
46 
47     private static final int PRIMARY_USER_ID = 0;
48 
49     private final List<String> mBaseRestrictions = new ArrayList<>();
50     private final List<String> mGuestRestrictions = new ArrayList<>();
51     private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
52     private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
53     private final Set<Integer> mManagedProfiles = new HashSet<>();
54     private final Set<String> mEnabledTypes = new HashSet<>();
55     private boolean mIsQuietModeEnabled = false;
56     private int[] profileIdsForUser = new int[0];
57     private boolean mUserSwitchEnabled;
58 
59     private @UserManager.UserSwitchabilityResult int mSwitchabilityStatus =
60             UserManager.SWITCHABILITY_STATUS_OK;
61     private final Map<Integer, Integer> mSameProfileGroupIds = Maps.newHashMap();
62 
addProfile(UserInfo userInfo)63     public void addProfile(UserInfo userInfo) {
64         mUserProfileInfos.add(userInfo);
65     }
66 
67     @Resetter
reset()68     public static void reset() {
69         sIsSupportsMultipleUsers = false;
70     }
71 
72     @Implementation
getProfiles(@serIdInt int userHandle)73     protected List<UserInfo> getProfiles(@UserIdInt int userHandle) {
74         return mUserProfileInfos;
75     }
76 
77     @Implementation
getProfileIds(@serIdInt int userHandle, boolean enabledOnly)78     protected int[] getProfileIds(@UserIdInt int userHandle, boolean enabledOnly) {
79         int[] ids = new int[mUserProfileInfos.size()];
80         for (int i = 0; i < mUserProfileInfos.size(); i++) {
81             ids[i] = mUserProfileInfos.get(i).id;
82         }
83         return ids;
84     }
85 
86     @Implementation
getCredentialOwnerProfile(@serIdInt int userHandle)87     protected int getCredentialOwnerProfile(@UserIdInt int userHandle) {
88         return userHandle;
89     }
90 
91     @Implementation
hasBaseUserRestriction(String restrictionKey, UserHandle userHandle)92     protected boolean hasBaseUserRestriction(String restrictionKey, UserHandle userHandle) {
93         return mBaseRestrictions.contains(restrictionKey);
94     }
95 
addBaseUserRestriction(String restriction)96     public void addBaseUserRestriction(String restriction) {
97         mBaseRestrictions.add(restriction);
98     }
99 
100     @Implementation
getDefaultGuestRestrictions()101     protected Bundle getDefaultGuestRestrictions() {
102         Bundle bundle = new Bundle();
103         mGuestRestrictions.forEach(restriction -> bundle.putBoolean(restriction, true));
104         return bundle;
105     }
106 
addGuestUserRestriction(String restriction)107     public void addGuestUserRestriction(String restriction) {
108         mGuestRestrictions.add(restriction);
109     }
110 
111     @Implementation
hasUserRestriction(String restrictionKey)112     protected boolean hasUserRestriction(String restrictionKey) {
113         return hasUserRestriction(restrictionKey, UserHandle.of(UserHandle.myUserId()));
114     }
115 
getShadow()116     public static ShadowUserManager getShadow() {
117         return (ShadowUserManager) Shadow.extract(
118                 RuntimeEnvironment.application.getSystemService(UserManager.class));
119     }
120 
121     @Implementation
getUserRestrictionSources( String restrictionKey, UserHandle userHandle)122     protected List<EnforcingUser> getUserRestrictionSources(
123             String restrictionKey, UserHandle userHandle) {
124         // Return empty list when there is no enforcing user, otherwise might trigger
125         // NullPointer Exception in RestrictedLockUtils.checkIfRestrictionEnforced.
126         List<EnforcingUser> enforcingUsers =
127                 mRestrictionSources.get(restrictionKey + userHandle.getIdentifier());
128         return enforcingUsers == null ? Collections.emptyList() : enforcingUsers;
129     }
130 
setUserRestrictionSources( String restrictionKey, UserHandle userHandle, List<EnforcingUser> enforcers)131     public void setUserRestrictionSources(
132             String restrictionKey, UserHandle userHandle, List<EnforcingUser> enforcers) {
133         mRestrictionSources.put(restrictionKey + userHandle.getIdentifier(), enforcers);
134     }
135 
136     @Implementation
isQuietModeEnabled(UserHandle userHandle)137     protected boolean isQuietModeEnabled(UserHandle userHandle) {
138         return mIsQuietModeEnabled;
139     }
140 
setQuietModeEnabled(boolean enabled)141     public void setQuietModeEnabled(boolean enabled) {
142         mIsQuietModeEnabled = enabled;
143     }
144 
145     @Implementation
getProfileIdsWithDisabled(@serIdInt int userId)146     protected int[] getProfileIdsWithDisabled(@UserIdInt int userId) {
147         return profileIdsForUser;
148     }
149 
setProfileIdsWithDisabled(int[] profileIds)150     public void setProfileIdsWithDisabled(int[] profileIds) {
151         profileIdsForUser = profileIds;
152     }
153 
154     @Implementation
isUserSwitcherEnabled()155     protected boolean isUserSwitcherEnabled() {
156         return mUserSwitchEnabled;
157     }
158 
159     @Implementation
isManagedProfile(int userId)160     protected boolean isManagedProfile(int userId) {
161         return mManagedProfiles.contains(userId);
162     }
163 
setManagedProfiles(Set<Integer> profileIds)164     public void setManagedProfiles(Set<Integer> profileIds) {
165         mManagedProfiles.clear();
166         mManagedProfiles.addAll(profileIds);
167     }
168 
setUserSwitcherEnabled(boolean userSwitchEnabled)169     public void setUserSwitcherEnabled(boolean userSwitchEnabled) {
170         mUserSwitchEnabled = userSwitchEnabled;
171     }
172 
173     @Implementation
supportsMultipleUsers()174     protected static boolean supportsMultipleUsers() {
175         return sIsSupportsMultipleUsers;
176     }
177 
178     @Implementation
isSameProfileGroup(@serIdInt int userId, int otherUserId)179     protected boolean isSameProfileGroup(@UserIdInt int userId, int otherUserId) {
180         return mSameProfileGroupIds.containsKey(userId)
181                 && mSameProfileGroupIds.get(userId) == otherUserId
182                 || mSameProfileGroupIds.containsKey(otherUserId)
183                 && mSameProfileGroupIds.get(otherUserId) == userId;
184     }
185 
getSameProfileGroupIds()186     public Map<Integer, Integer> getSameProfileGroupIds() {
187         return mSameProfileGroupIds;
188     }
189 
setSupportsMultipleUsers(boolean supports)190     public void setSupportsMultipleUsers(boolean supports) {
191         sIsSupportsMultipleUsers = supports;
192     }
193 
194     @Implementation
getUserInfo(@serIdInt int userId)195     protected UserInfo getUserInfo(@UserIdInt int userId) {
196         return mUserProfileInfos.stream()
197                 .filter(userInfo -> userInfo.id == userId)
198                 .findFirst()
199                 .orElse(super.getUserInfo(userId));
200     }
201 
202     @Implementation
getUserSwitchability()203     protected @UserManager.UserSwitchabilityResult int getUserSwitchability() {
204         return mSwitchabilityStatus;
205     }
206 
setSwitchabilityStatus(@serManager.UserSwitchabilityResult int newStatus)207     public void setSwitchabilityStatus(@UserManager.UserSwitchabilityResult int newStatus) {
208         mSwitchabilityStatus = newStatus;
209     }
210 
211     @Implementation
isUserTypeEnabled(String userType)212     protected boolean isUserTypeEnabled(String userType) {
213         return mEnabledTypes.contains(userType);
214     }
215 
setUserTypeEnabled(String type, boolean enabled)216     public void setUserTypeEnabled(String type, boolean enabled) {
217         if (enabled) {
218             mEnabledTypes.add(type);
219         } else {
220             mEnabledTypes.remove(type);
221         }
222     }
223 
224     @Implementation
getPrimaryUser()225     protected UserInfo getPrimaryUser() {
226         return new UserInfo(PRIMARY_USER_ID, null, null,
227                 UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
228     }
229 
setUserEphemeral(@serIdInt int userId, boolean enableEphemeral)230     protected boolean setUserEphemeral(@UserIdInt int userId, boolean enableEphemeral) {
231         UserInfo userInfo = mUserProfileInfos.stream()
232                 .filter(user -> user.id == userId)
233                 .findFirst()
234                 .orElse(super.getUserInfo(userId));
235 
236         boolean isSuccess = false;
237         boolean isEphemeralUser =
238                         (userInfo.flags & UserInfo.FLAG_EPHEMERAL) != 0;
239         boolean isEphemeralOnCreateUser =
240                 (userInfo.flags & UserInfo.FLAG_EPHEMERAL_ON_CREATE)
241                     != 0;
242         // when user is created in ephemeral mode via FLAG_EPHEMERAL
243         // its state cannot be changed.
244         // FLAG_EPHEMERAL_ON_CREATE is used to keep track of this state
245         if (!isEphemeralOnCreateUser) {
246             isSuccess = true;
247             if (isEphemeralUser != enableEphemeral) {
248                 if (enableEphemeral) {
249                     userInfo.flags |= UserInfo.FLAG_EPHEMERAL;
250                 } else {
251                     userInfo.flags &= ~UserInfo.FLAG_EPHEMERAL;
252                 }
253             }
254         }
255         return isSuccess;
256     }
257 }
258