1742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani/*
2742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Copyright (C) 2011 The Android Open Source Project
3742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *
4742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
5742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * you may not use this file except in compliance with the License.
6742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * You may obtain a copy of the License at
7742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *
8742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
9742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *
10742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Unless required by applicable law or agreed to in writing, software
11742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
12742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * See the License for the specific language governing permissions and
14742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * limitations under the License.
15742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani */
16742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
17742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasanipackage android.os;
18742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
19cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tateimport android.annotation.SystemApi;
20c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghinaimport android.util.SparseArray;
21c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina
22a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport java.io.PrintWriter;
23c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghinaimport java.util.HashMap;
24a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
25742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani/**
26f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn * Representation of a user on the device.
27742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani */
2879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackbornpublic final class UserHandle implements Parcelable {
29742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    /**
3079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @hide Range of uids allocated for a user.
31742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     */
32742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final int PER_USER_RANGE = 100000;
33742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
3479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide A user id to indicate all users on the device */
35742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final int USER_ALL = -1;
36742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
377767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn    /** @hide A user handle to indicate all users on the device */
387767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn    public static final UserHandle ALL = new UserHandle(USER_ALL);
397767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn
4079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide A user id to indicate the currently active user */
418264408f5995534f8e3147b001664ea0df52aaa5Amith Yamasani    public static final int USER_CURRENT = -2;
428264408f5995534f8e3147b001664ea0df52aaa5Amith Yamasani
435ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn    /** @hide A user handle to indicate the current user of the device */
445ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn    public static final UserHandle CURRENT = new UserHandle(USER_CURRENT);
455ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn
465ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn    /** @hide A user id to indicate that we would like to send to the current
475ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn     *  user, but if this is calling from a user process then we will send it
48b6e0cb97b7d8e4acf345efc8066f1587408b83e0Alan Viverette     *  to the caller's user instead of failing with a security exception */
498a9f5d42a5cc373439ee8bbb9185dcce9086770dDianne Hackborn    public static final int USER_CURRENT_OR_SELF = -3;
505ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn
515ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn    /** @hide A user handle to indicate that we would like to send to the current
525ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn     *  user, but if this is calling from a user process then we will send it
53b6e0cb97b7d8e4acf345efc8066f1587408b83e0Alan Viverette     *  to the caller's user instead of failing with a security exception */
545ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn    public static final UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);
555ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn
5679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide An undefined user id */
5779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public static final int USER_NULL = -10000;
5879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
5979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide A user id constant to indicate the "owner" user of the device */
60aac71ff465399251fa8e830407f2917b986988d9Christopher Tate    public static final int USER_OWNER = 0;
618264408f5995534f8e3147b001664ea0df52aaa5Amith Yamasani
625ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn    /** @hide A user handle to indicate the primary/owner user of the device */
635ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn    public static final UserHandle OWNER = new UserHandle(USER_OWNER);
645ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn
65742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    /**
6679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @hide Enable multi-user related side effects. Set this to false if
6779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * there are problems with single user use-cases.
6879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     */
69742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final boolean MU_ENABLED = true;
70742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
7179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    final int mHandle;
7279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
73c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    private static final SparseArray<UserHandle> userHandles = new SparseArray<UserHandle>();
74c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina
75742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    /**
76742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * Checks to see if the user id is the same for the two uids, i.e., they belong to the same
77742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * user.
78742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @hide
79742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     */
80742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final boolean isSameUser(int uid1, int uid2) {
81742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        return getUserId(uid1) == getUserId(uid2);
82742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
83742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
84742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    /**
85742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * Checks to see if both uids are referring to the same app id, ignoring the user id part of the
86742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * uids.
87742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @param uid1 uid to compare
88742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @param uid2 other uid to compare
89742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @return whether the appId is the same for both uids
90742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @hide
91742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     */
92742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final boolean isSameApp(int uid1, int uid2) {
93742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        return getAppId(uid1) == getAppId(uid2);
94742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
95742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
9679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide */
97a573f6a1d9b12393fbdfd2c0850499973849854bDianne Hackborn    public static final boolean isIsolated(int uid) {
98d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey        if (uid > 0) {
99d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey            final int appId = getAppId(uid);
100d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey            return appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID;
101d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey        } else {
102d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey            return false;
103d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey        }
104a573f6a1d9b12393fbdfd2c0850499973849854bDianne Hackborn    }
105a573f6a1d9b12393fbdfd2c0850499973849854bDianne Hackborn
10679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide */
1078a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey    public static boolean isApp(int uid) {
1088a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey        if (uid > 0) {
109d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey            final int appId = getAppId(uid);
110d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey            return appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID;
1118a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey        } else {
1128a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey            return false;
1138a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey        }
1148a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey    }
1158a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey
116742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    /**
117742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * Returns the user id for a given uid.
118742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @hide
119742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     */
120742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final int getUserId(int uid) {
121742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (MU_ENABLED) {
122742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return uid / PER_USER_RANGE;
123742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
124742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return 0;
125742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
126742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
127742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
12879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide */
12937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    public static final int getCallingUserId() {
13037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        return getUserId(Binder.getCallingUid());
13137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
13237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
133c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    /** @hide */
134c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    public static final UserHandle getCallingUserHandle() {
135c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        int userId = getUserId(Binder.getCallingUid());
136c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        UserHandle userHandle = userHandles.get(userId);
137c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        // Intentionally not synchronized to save time
138c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        if (userHandle == null) {
139c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina            userHandle = new UserHandle(userId);
140c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina            userHandles.put(userId, userHandle);
141c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        }
142c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        return userHandle;
143c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    }
144c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina
145742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    /**
146742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * Returns the uid that is composed from the userId and the appId.
147742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @hide
148742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     */
149742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final int getUid(int userId, int appId) {
150742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (MU_ENABLED) {
151742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
152742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
153742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return appId;
154742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
155742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
156742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
157742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    /**
158742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * Returns the app id (or base uid) for a given uid, stripping out the user id from it.
159742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     * @hide
160742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani     */
161742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    public static final int getAppId(int uid) {
162742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        return uid % PER_USER_RANGE;
163742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
164483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani
165483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    /**
166e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee     * Returns the gid shared between all apps with this userId.
167e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee     * @hide
168e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee     */
169e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee    public static final int getUserGid(int userId) {
170e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee        return getUid(userId, Process.SHARED_USER_GID);
171e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee    }
172e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee
173e66b6890ee59d108ae5c608f6ec8d4ad20cb06a8Robin Lee    /**
174e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root     * Returns the shared app gid for a given uid or appId.
175e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root     * @hide
176e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root     */
177e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root    public static final int getSharedAppGid(int id) {
178e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root        return Process.FIRST_SHARED_APPLICATION_GID + (id % PER_USER_RANGE)
179e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root                - Process.FIRST_APPLICATION_UID;
180e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root    }
181e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root
182e091f22e226f7177e45e23850670c1ad9b63fd75Kenny Root    /**
183a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     * Generate a text representation of the uid, breaking out its individual
184a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     * components -- user, app, isolated, etc.
185a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     * @hide
186a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     */
187a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public static void formatUid(StringBuilder sb, int uid) {
188a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (uid < Process.FIRST_APPLICATION_UID) {
189a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            sb.append(uid);
190a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        } else {
191a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            sb.append('u');
192a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            sb.append(getUserId(uid));
193a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            final int appId = getAppId(uid);
194a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
195a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                sb.append('i');
196a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                sb.append(appId - Process.FIRST_ISOLATED_UID);
197a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn            } else if (appId >= Process.FIRST_APPLICATION_UID) {
198a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                sb.append('a');
199a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn                sb.append(appId - Process.FIRST_APPLICATION_UID);
200a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn            } else {
201a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn                sb.append('s');
202a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                sb.append(appId);
203a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
204a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
205a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
206a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
207a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    /**
208a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     * Generate a text representation of the uid, breaking out its individual
209a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     * components -- user, app, isolated, etc.
210a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     * @hide
211a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn     */
212a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public static void formatUid(PrintWriter pw, int uid) {
213a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (uid < Process.FIRST_APPLICATION_UID) {
214a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            pw.print(uid);
215a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        } else {
216a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            pw.print('u');
217a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            pw.print(getUserId(uid));
218a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            final int appId = getAppId(uid);
219a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
220a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                pw.print('i');
221a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                pw.print(appId - Process.FIRST_ISOLATED_UID);
222a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn            } else if (appId >= Process.FIRST_APPLICATION_UID) {
223a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                pw.print('a');
224a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn                pw.print(appId - Process.FIRST_APPLICATION_UID);
225a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn            } else {
226a4cc205ee840a5374a96c9635dc5121d82a3eaf9Dianne Hackborn                pw.print('s');
227a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                pw.print(appId);
228a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
229a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
230a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
231a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
232a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    /**
233483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani     * Returns the user id of the current process
234483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani     * @return user id of the current process
23579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @hide
236483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani     */
2370e8d7d63ba439cc0604af7055679dae3d30fdc48Amith Yamasani    @SystemApi
238483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    public static final int myUserId() {
239483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani        return getUserId(Process.myUid());
240483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    }
24179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
242cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate    /**
243cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate     * Returns true if this UserHandle refers to the owner user; false otherwise.
244cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate     * @return true if this UserHandle refers to the owner user; false otherwise.
245cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate     * @hide
246cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate     */
247cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate    @SystemApi
248cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate    public final boolean isOwner() {
249cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate        return this.equals(OWNER);
250cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate    }
251cbd7a6ecbb7aa5a4ea146cf05f1ec254eb3e60b9Christopher Tate
25279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /** @hide */
25379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public UserHandle(int h) {
25479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        mHandle = h;
25579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
25679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
2570e8d7d63ba439cc0604af7055679dae3d30fdc48Amith Yamasani    /**
2580e8d7d63ba439cc0604af7055679dae3d30fdc48Amith Yamasani     * Returns the userId stored in this UserHandle.
2590e8d7d63ba439cc0604af7055679dae3d30fdc48Amith Yamasani     * @hide
2600e8d7d63ba439cc0604af7055679dae3d30fdc48Amith Yamasani     */
2610e8d7d63ba439cc0604af7055679dae3d30fdc48Amith Yamasani    @SystemApi
26279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public int getIdentifier() {
26379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        return mHandle;
26479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
26579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
26679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    @Override
26779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public String toString() {
26879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        return "UserHandle{" + mHandle + "}";
26979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
27079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
27179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    @Override
27279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public boolean equals(Object obj) {
27379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        try {
27479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn            if (obj != null) {
27579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn                UserHandle other = (UserHandle)obj;
27679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn                return mHandle == other.mHandle;
27779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn            }
27879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        } catch (ClassCastException e) {
27979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        }
28079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        return false;
28179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
28279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
28379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    @Override
28479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public int hashCode() {
28579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        return mHandle;
28679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
28779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
28879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public int describeContents() {
28979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        return 0;
29079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
29179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
29279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public void writeToParcel(Parcel out, int flags) {
29379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        out.writeInt(mHandle);
29479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
29579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
29679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /**
29779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * Write a UserHandle to a Parcel, handling null pointers.  Must be
29879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * read with {@link #readFromParcel(Parcel)}.
29979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     *
30079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @param h The UserHandle to be written.
30179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @param out The Parcel in which the UserHandle will be placed.
30279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     *
30379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @see #readFromParcel(Parcel)
30479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     */
30579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public static void writeToParcel(UserHandle h, Parcel out) {
30679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        if (h != null) {
30779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn            h.writeToParcel(out, 0);
30879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        } else {
30979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn            out.writeInt(USER_NULL);
31079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        }
31179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
31279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
31379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /**
31479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * Read a UserHandle from a Parcel that was previously written
31579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * with {@link #writeToParcel(UserHandle, Parcel)}, returning either
31679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * a null or new object as appropriate.
31779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     *
31879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @param in The Parcel from which to read the UserHandle
31979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @return Returns a new UserHandle matching the previously written
32079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * object, or null if a null had been written.
32179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     *
32279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @see #writeToParcel(UserHandle, Parcel)
32379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     */
32479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public static UserHandle readFromParcel(Parcel in) {
32579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        int h = in.readInt();
32679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        return h != USER_NULL ? new UserHandle(h) : null;
32779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
32879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
32979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public static final Parcelable.Creator<UserHandle> CREATOR
33079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn            = new Parcelable.Creator<UserHandle>() {
33179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        public UserHandle createFromParcel(Parcel in) {
33279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn            return new UserHandle(in);
33379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        }
33479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
33579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        public UserHandle[] newArray(int size) {
33679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn            return new UserHandle[size];
33779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        }
33879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    };
33979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn
34079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    /**
34179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * Instantiate a new UserHandle from the data in a Parcel that was
34279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * previously written with {@link #writeToParcel(Parcel, int)}.  Note that you
34379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * must not use this with data written by
34479af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * {@link #writeToParcel(UserHandle, Parcel)} since it is not possible
34579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * to handle a null UserHandle here.
34679af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     *
34779af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * @param in The Parcel containing the previously written UserHandle,
34879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     * positioned at the location in the buffer where it was written.
34979af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn     */
35079af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    public UserHandle(Parcel in) {
35179af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn        mHandle = in.readInt();
35279af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn    }
353742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani}
354