1 /*
2  * Copyright (C) 2020 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.server.location.injector;
18 
19 import android.util.IndentingPrintWriter;
20 import android.util.IntArray;
21 import android.util.SparseArray;
22 
23 import com.android.internal.util.ArrayUtils;
24 import com.android.internal.util.Preconditions;
25 
26 import java.io.FileDescriptor;
27 
28 /**
29  * Version of UserInfoHelper for testing. By default there is one user that starts in a running
30  * state with a userId of 0;
31  */
32 public class FakeUserInfoHelper extends UserInfoHelper {
33 
34     public static final int DEFAULT_USERID = 0;
35 
36     private final IntArray mRunningUserIds;
37     private final IntArray mVisibleUserIds;
38     private final SparseArray<IntArray> mProfiles;
39 
40     private int mCurrentUserId;
41 
FakeUserInfoHelper()42     public FakeUserInfoHelper() {
43         mCurrentUserId = DEFAULT_USERID;
44         mRunningUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
45         mProfiles = new SparseArray<>();
46         mVisibleUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
47     }
48 
startUser(int userId)49     public void startUser(int userId) {
50         startUserInternal(userId, true);
51     }
52 
startUserInternal(int userId, boolean alwaysDispatch)53     private void startUserInternal(int userId, boolean alwaysDispatch) {
54         int idx = mRunningUserIds.indexOf(userId);
55         if (idx < 0) {
56             mRunningUserIds.add(userId);
57         } else if (!alwaysDispatch) {
58             return;
59         }
60 
61         dispatchOnUserStarted(userId);
62     }
63 
stopUser(int userId)64     public void stopUser(int userId) {
65         int idx = mRunningUserIds.indexOf(userId);
66         if (idx >= 0) {
67             mRunningUserIds.remove(idx);
68         }
69 
70         setUserInvisibleInternal(userId);
71         dispatchOnUserStopped(userId);
72     }
73 
setCurrentUserId(int parentUser)74     public void setCurrentUserId(int parentUser) {
75         setCurrentUserIds(parentUser, new int[]{parentUser});
76     }
77 
setCurrentUserIds(int parentUser, int[] currentProfileUserIds)78     public void setCurrentUserIds(int parentUser, int[] currentProfileUserIds) {
79         Preconditions.checkArgument(ArrayUtils.contains(currentProfileUserIds, parentUser));
80         int oldUserId = mCurrentUserId;
81         mCurrentUserId = parentUser;
82         mProfiles.put(parentUser,
83                 IntArray.fromArray(currentProfileUserIds, currentProfileUserIds.length));
84 
85         // ensure all profiles are started if they didn't exist before...
86         for (int userId : currentProfileUserIds) {
87             startUserInternal(userId, false);
88             setUserVisibleInternal(userId, true);
89         }
90 
91         if (oldUserId != mCurrentUserId) {
92             dispatchOnCurrentUserChanged(oldUserId, mCurrentUserId);
93             setUserVisibleInternal(mCurrentUserId, true);
94         }
95     }
96 
setUserVisibleInternal(int userId, boolean alwaysDispatch)97     private void setUserVisibleInternal(int userId, boolean alwaysDispatch) {
98         int idx = mVisibleUserIds.indexOf(userId);
99         if (idx < 0) {
100             mVisibleUserIds.add(userId);
101         } else if (!alwaysDispatch) {
102             return;
103         }
104         dispatchOnVisibleUserChanged(userId, true);
105     }
106 
setUserInvisibleInternal(int userId)107     private void setUserInvisibleInternal(int userId) {
108         int idx = mVisibleUserIds.indexOf(userId);
109         if (idx >= 0) {
110             mVisibleUserIds.remove(userId);
111         }
112         dispatchOnVisibleUserChanged(userId, false);
113     }
114 
setUserVisible(int userId, boolean visible)115     public void setUserVisible(int userId, boolean visible) {
116         if (visible) {
117             setUserVisibleInternal(userId, true);
118         } else {
119             setUserInvisibleInternal(userId);
120         }
121     }
122 
123     @Override
isCurrentUserId(int userId)124     public boolean isCurrentUserId(int userId) {
125         return ArrayUtils.contains(getProfileIds(mCurrentUserId), userId);
126     }
127 
128     @Override
getRunningUserIds()129     public int[] getRunningUserIds() {
130         return mRunningUserIds.toArray();
131     }
132 
133     @Override
getCurrentUserId()134     public int getCurrentUserId() {
135         return mCurrentUserId;
136     }
137 
138     @Override
isVisibleUserId(int userId)139     public boolean isVisibleUserId(int userId) {
140         return mVisibleUserIds.indexOf(userId) >= 0;
141     }
142 
143     @Override
getProfileIds(int userId)144     protected int[] getProfileIds(int userId) {
145         IntArray profiles = mProfiles.get(userId);
146         if (profiles != null) {
147             return profiles.toArray();
148         } else {
149             return new int[] {userId};
150         }
151     }
152 
153     @Override
dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args)154     public void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {}
155 }
156