1 /*
2  * Copyright (C) 2021 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.bedstead.nene.users;
18 
19 import android.util.Log;
20 
21 import androidx.annotation.Nullable;
22 
23 import com.android.bedstead.nene.TestApis;
24 
25 /**
26  * Representation of a user on an Android device.
27  *
28  * <p>{@link User} information represents the state of the device at construction time. To get an
29  * updated reflection of the user on the device, see {@link #resolve()}.
30  */
31 public final class User extends UserReference {
32 
33     private static final String LOG_TAG = "User";
34 
35     /* From UserInfo */
36     static final int FLAG_MANAGED_PROFILE = 0x00000020;
37 
38     public enum UserState {
39         NOT_RUNNING,
40         RUNNING_LOCKED,
41         RUNNING_UNLOCKED,
42         RUNNING_UNLOCKING,
43         STOPPING,
44         SHUTDOWN,
45         UNKNOWN;
46 
fromDumpSysValue(String value)47         static UserState fromDumpSysValue(String value) {
48             try {
49                 return UserState.valueOf(value);
50             } catch (IllegalArgumentException e) {
51                 if (value.equals("-1")) {
52                     return NOT_RUNNING;
53                 }
54                 Log.w(LOG_TAG, "Unknown user state string: " + value);
55                 return UNKNOWN;
56             }
57         }
58     }
59 
60     static final class MutableUser {
61         Integer mId;
62         @Nullable Integer mSerialNo;
63         @Nullable String mName;
64         @Nullable UserType mType;
65         @Nullable Boolean mHasProfileOwner;
66         @Nullable Boolean mIsPrimary;
67         @Nullable UserState mState;
68         @Nullable Boolean mIsRemoving;
69         @Nullable Integer mFlags;
70         @Nullable UserReference mParent;
71     }
72 
73     final MutableUser mMutableUser;
74 
User(TestApis testApis, MutableUser mutableUser)75     User(TestApis testApis, MutableUser mutableUser) {
76         super(testApis, mutableUser.mId);
77         mMutableUser = mutableUser;
78     }
79 
80     /** Get the serial number of the user. */
serialNo()81     public Integer serialNo() {
82         return mMutableUser.mSerialNo;
83     }
84 
85     /** Get the name of the user. */
name()86     public String name() {
87         return mMutableUser.mName;
88     }
89 
90     /** Get the {@link UserState} of the user. */
state()91     public UserState state() {
92         return mMutableUser.mState;
93     }
94 
95     /** True if the user is currently being removed. */
isRemoving()96     public boolean isRemoving() {
97         return mMutableUser.mIsRemoving;
98     }
99 
100     /**
101      * Get the user type.
102      */
type()103     public UserType type() {
104         return mMutableUser.mType;
105     }
106 
107     /** {@code true} if the user has a profile owner. */
hasProfileOwner()108     public Boolean hasProfileOwner() {
109         return mMutableUser.mHasProfileOwner;
110     }
111 
112     /**
113      * Return {@code true} if this is the primary user.
114      */
isPrimary()115     public Boolean isPrimary() {
116         return mMutableUser.mIsPrimary;
117     }
118 
hasFlag(int flag)119     boolean hasFlag(int flag) {
120         if (mMutableUser.mFlags == null) {
121             return false;
122         }
123         return (mMutableUser.mFlags & flag) != 0;
124     }
125 
126     /**
127      * Return the parent of this profile.
128      *
129      * <p>Returns {@code null} if this user is not a profile.
130      */
131     @Nullable
parent()132     public UserReference parent() {
133         return mMutableUser.mParent;
134     }
135 
136     @Override
toString()137     public String toString() {
138         StringBuilder stringBuilder = new StringBuilder("User{");
139         stringBuilder.append("id=" + mMutableUser.mId);
140         stringBuilder.append(", serialNo=" + mMutableUser.mSerialNo);
141         stringBuilder.append(", name=" + mMutableUser.mName);
142         stringBuilder.append(", type=" + mMutableUser.mType);
143         stringBuilder.append(", hasProfileOwner" + mMutableUser.mHasProfileOwner);
144         stringBuilder.append(", isPrimary=" + mMutableUser.mIsPrimary);
145         stringBuilder.append(", state=" + mMutableUser.mState);
146         stringBuilder.append(", parent=" + mMutableUser.mParent);
147         stringBuilder.append("}");
148         return stringBuilder.toString();
149     }
150 }
151