UserHandle.java revision 79af1dd54c16cde063152922b42c96d72ae9eca8
1/*
2 * Copyright (C) 2011 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
17package android.os;
18
19/**
20 * Representation of a user on the device.
21 */
22public final class UserHandle implements Parcelable {
23    /**
24     * @hide Range of uids allocated for a user.
25     */
26    public static final int PER_USER_RANGE = 100000;
27
28    /** @hide A user id to indicate all users on the device */
29    public static final int USER_ALL = -1;
30
31    /** @hide A user id to indicate the currently active user */
32    public static final int USER_CURRENT = -2;
33
34    /** @hide An undefined user id */
35    public static final int USER_NULL = -10000;
36
37    /** @hide A user id constant to indicate the "owner" user of the device */
38    public static final int USER_OWNER = 0;
39
40    /**
41     * @hide Enable multi-user related side effects. Set this to false if
42     * there are problems with single user use-cases.
43     */
44    public static final boolean MU_ENABLED = true;
45
46    final int mHandle;
47
48    /**
49     * Checks to see if the user id is the same for the two uids, i.e., they belong to the same
50     * user.
51     * @hide
52     */
53    public static final boolean isSameUser(int uid1, int uid2) {
54        return getUserId(uid1) == getUserId(uid2);
55    }
56
57    /**
58     * Checks to see if both uids are referring to the same app id, ignoring the user id part of the
59     * uids.
60     * @param uid1 uid to compare
61     * @param uid2 other uid to compare
62     * @return whether the appId is the same for both uids
63     * @hide
64     */
65    public static final boolean isSameApp(int uid1, int uid2) {
66        return getAppId(uid1) == getAppId(uid2);
67    }
68
69    /** @hide */
70    public static final boolean isIsolated(int uid) {
71        uid = getAppId(uid);
72        return uid >= Process.FIRST_ISOLATED_UID && uid <= Process.LAST_ISOLATED_UID;
73    }
74
75    /** @hide */
76    public static boolean isApp(int uid) {
77        if (uid > 0) {
78            uid = UserHandle.getAppId(uid);
79            return uid >= Process.FIRST_APPLICATION_UID && uid <= Process.LAST_APPLICATION_UID;
80        } else {
81            return false;
82        }
83    }
84
85    /**
86     * Returns the user id for a given uid.
87     * @hide
88     */
89    public static final int getUserId(int uid) {
90        if (MU_ENABLED) {
91            return uid / PER_USER_RANGE;
92        } else {
93            return 0;
94        }
95    }
96
97    /** @hide */
98    public static final int getCallingUserId() {
99        return getUserId(Binder.getCallingUid());
100    }
101
102    /**
103     * Returns the uid that is composed from the userId and the appId.
104     * @hide
105     */
106    public static final int getUid(int userId, int appId) {
107        if (MU_ENABLED) {
108            return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
109        } else {
110            return appId;
111        }
112    }
113
114    /**
115     * Returns the app id (or base uid) for a given uid, stripping out the user id from it.
116     * @hide
117     */
118    public static final int getAppId(int uid) {
119        return uid % PER_USER_RANGE;
120    }
121
122    /**
123     * Returns the user id of the current process
124     * @return user id of the current process
125     * @hide
126     */
127    public static final int myUserId() {
128        return getUserId(Process.myUid());
129    }
130
131    /** @hide */
132    public UserHandle(int h) {
133        mHandle = h;
134    }
135
136    /** @hide */
137    public int getIdentifier() {
138        return mHandle;
139    }
140
141    @Override
142    public String toString() {
143        return "UserHandle{" + mHandle + "}";
144    }
145
146    @Override
147    public boolean equals(Object obj) {
148        try {
149            if (obj != null) {
150                UserHandle other = (UserHandle)obj;
151                return mHandle == other.mHandle;
152            }
153        } catch (ClassCastException e) {
154        }
155        return false;
156    }
157
158    @Override
159    public int hashCode() {
160        return mHandle;
161    }
162
163    public int describeContents() {
164        return 0;
165    }
166
167    public void writeToParcel(Parcel out, int flags) {
168        out.writeInt(mHandle);
169    }
170
171    /**
172     * Write a UserHandle to a Parcel, handling null pointers.  Must be
173     * read with {@link #readFromParcel(Parcel)}.
174     *
175     * @param h The UserHandle to be written.
176     * @param out The Parcel in which the UserHandle will be placed.
177     *
178     * @see #readFromParcel(Parcel)
179     */
180    public static void writeToParcel(UserHandle h, Parcel out) {
181        if (h != null) {
182            h.writeToParcel(out, 0);
183        } else {
184            out.writeInt(USER_NULL);
185        }
186    }
187
188    /**
189     * Read a UserHandle from a Parcel that was previously written
190     * with {@link #writeToParcel(UserHandle, Parcel)}, returning either
191     * a null or new object as appropriate.
192     *
193     * @param in The Parcel from which to read the UserHandle
194     * @return Returns a new UserHandle matching the previously written
195     * object, or null if a null had been written.
196     *
197     * @see #writeToParcel(UserHandle, Parcel)
198     */
199    public static UserHandle readFromParcel(Parcel in) {
200        int h = in.readInt();
201        return h != USER_NULL ? new UserHandle(h) : null;
202    }
203
204    public static final Parcelable.Creator<UserHandle> CREATOR
205            = new Parcelable.Creator<UserHandle>() {
206        public UserHandle createFromParcel(Parcel in) {
207            return new UserHandle(in);
208        }
209
210        public UserHandle[] newArray(int size) {
211            return new UserHandle[size];
212        }
213    };
214
215    /**
216     * Instantiate a new UserHandle from the data in a Parcel that was
217     * previously written with {@link #writeToParcel(Parcel, int)}.  Note that you
218     * must not use this with data written by
219     * {@link #writeToParcel(UserHandle, Parcel)} since it is not possible
220     * to handle a null UserHandle here.
221     *
222     * @param in The Parcel containing the previously written UserHandle,
223     * positioned at the location in the buffer where it was written.
224     */
225    public UserHandle(Parcel in) {
226        mHandle = in.readInt();
227    }
228}
229