Home | History | Annotate | Download | only in os
      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 
     17 package android.os;
     18 
     19 import android.annotation.AppIdInt;
     20 import android.annotation.NonNull;
     21 import android.annotation.SystemApi;
     22 import android.annotation.TestApi;
     23 import android.annotation.UnsupportedAppUsage;
     24 import android.annotation.UserIdInt;
     25 
     26 import java.io.PrintWriter;
     27 
     28 /**
     29  * Representation of a user on the device.
     30  */
     31 public final class UserHandle implements Parcelable {
     32     // NOTE: keep logic in sync with system/core/libcutils/multiuser.c
     33 
     34     /**
     35      * @hide Range of uids allocated for a user.
     36      */
     37     @UnsupportedAppUsage
     38     public static final int PER_USER_RANGE = 100000;
     39 
     40     /** @hide A user id to indicate all users on the device */
     41     @UnsupportedAppUsage
     42     public static final @UserIdInt int USER_ALL = -1;
     43 
     44     /** @hide A user handle to indicate all users on the device */
     45     @SystemApi
     46     @TestApi
     47     public static final @NonNull UserHandle ALL = new UserHandle(USER_ALL);
     48 
     49     /** @hide A user id to indicate the currently active user */
     50     @UnsupportedAppUsage
     51     public static final @UserIdInt int USER_CURRENT = -2;
     52 
     53     /** @hide A user handle to indicate the current user of the device */
     54     @SystemApi
     55     @TestApi
     56     public static final @NonNull UserHandle CURRENT = new UserHandle(USER_CURRENT);
     57 
     58     /** @hide A user id to indicate that we would like to send to the current
     59      *  user, but if this is calling from a user process then we will send it
     60      *  to the caller's user instead of failing with a security exception */
     61     @UnsupportedAppUsage
     62     public static final @UserIdInt int USER_CURRENT_OR_SELF = -3;
     63 
     64     /** @hide A user handle to indicate that we would like to send to the current
     65      *  user, but if this is calling from a user process then we will send it
     66      *  to the caller's user instead of failing with a security exception */
     67     @UnsupportedAppUsage
     68     public static final @NonNull UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);
     69 
     70     /** @hide An undefined user id */
     71     @UnsupportedAppUsage
     72     public static final @UserIdInt int USER_NULL = -10000;
     73 
     74     /**
     75      * @hide A user id constant to indicate the "owner" user of the device
     76      * @deprecated Consider using either {@link UserHandle#USER_SYSTEM} constant or
     77      * check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
     78      */
     79     @UnsupportedAppUsage
     80     @Deprecated
     81     public static final @UserIdInt int USER_OWNER = 0;
     82 
     83     /**
     84      * @hide A user handle to indicate the primary/owner user of the device
     85      * @deprecated Consider using either {@link UserHandle#SYSTEM} constant or
     86      * check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
     87      */
     88     @UnsupportedAppUsage
     89     @Deprecated
     90     public static final @NonNull UserHandle OWNER = new UserHandle(USER_OWNER);
     91 
     92     /** @hide A user id constant to indicate the "system" user of the device */
     93     @UnsupportedAppUsage
     94     public static final @UserIdInt int USER_SYSTEM = 0;
     95 
     96     /** @hide A user serial constant to indicate the "system" user of the device */
     97     @UnsupportedAppUsage
     98     public static final int USER_SERIAL_SYSTEM = 0;
     99 
    100     /** @hide A user handle to indicate the "system" user of the device */
    101     @SystemApi
    102     @TestApi
    103     public static final @NonNull UserHandle SYSTEM = new UserHandle(USER_SYSTEM);
    104 
    105     /**
    106      * @hide Enable multi-user related side effects. Set this to false if
    107      * there are problems with single user use-cases.
    108      */
    109     @UnsupportedAppUsage
    110     public static final boolean MU_ENABLED = true;
    111 
    112     /** @hide */
    113     @UnsupportedAppUsage
    114     public static final int ERR_GID = -1;
    115     /** @hide */
    116     @UnsupportedAppUsage
    117     public static final int AID_ROOT = android.os.Process.ROOT_UID;
    118     /** @hide */
    119     @UnsupportedAppUsage
    120     public static final int AID_APP_START = android.os.Process.FIRST_APPLICATION_UID;
    121     /** @hide */
    122     @UnsupportedAppUsage
    123     public static final int AID_APP_END = android.os.Process.LAST_APPLICATION_UID;
    124     /** @hide */
    125     @UnsupportedAppUsage
    126     public static final int AID_SHARED_GID_START = android.os.Process.FIRST_SHARED_APPLICATION_GID;
    127     /** @hide */
    128     @UnsupportedAppUsage
    129     public static final int AID_CACHE_GID_START = android.os.Process.FIRST_APPLICATION_CACHE_GID;
    130 
    131     @UnsupportedAppUsage
    132     final int mHandle;
    133 
    134     /**
    135      * Checks to see if the user id is the same for the two uids, i.e., they belong to the same
    136      * user.
    137      * @hide
    138      */
    139     public static boolean isSameUser(int uid1, int uid2) {
    140         return getUserId(uid1) == getUserId(uid2);
    141     }
    142 
    143     /**
    144      * Checks to see if both uids are referring to the same app id, ignoring the user id part of the
    145      * uids.
    146      * @param uid1 uid to compare
    147      * @param uid2 other uid to compare
    148      * @return whether the appId is the same for both uids
    149      * @hide
    150      */
    151     @UnsupportedAppUsage
    152     public static boolean isSameApp(int uid1, int uid2) {
    153         return getAppId(uid1) == getAppId(uid2);
    154     }
    155 
    156     /**
    157      * Whether a UID is an "isolated" UID.
    158      * @hide
    159      */
    160     @UnsupportedAppUsage
    161     public static boolean isIsolated(int uid) {
    162         if (uid > 0) {
    163             return Process.isIsolated(uid);
    164         } else {
    165             return false;
    166         }
    167     }
    168 
    169     /**
    170      * Whether a UID belongs to a regular app. *Note* "Not a regular app" does not mean
    171      * "it's system", because of isolated UIDs. Use {@link #isCore} for that.
    172      * @hide
    173      */
    174     @TestApi
    175     public static boolean isApp(int uid) {
    176         if (uid > 0) {
    177             final int appId = getAppId(uid);
    178             return appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID;
    179         } else {
    180             return false;
    181         }
    182     }
    183 
    184     /**
    185      * Whether a UID belongs to a system core component or not.
    186      * @hide
    187      */
    188     public static boolean isCore(int uid) {
    189         if (uid >= 0) {
    190             final int appId = getAppId(uid);
    191             return appId < Process.FIRST_APPLICATION_UID;
    192         } else {
    193             return false;
    194         }
    195     }
    196 
    197     /**
    198      * Returns the user for a given uid.
    199      * @param uid A uid for an application running in a particular user.
    200      * @return A {@link UserHandle} for that user.
    201      */
    202     public static UserHandle getUserHandleForUid(int uid) {
    203         return of(getUserId(uid));
    204     }
    205 
    206     /**
    207      * Returns the user id for a given uid.
    208      * @hide
    209      */
    210     @UnsupportedAppUsage
    211     public static @UserIdInt int getUserId(int uid) {
    212         if (MU_ENABLED) {
    213             return uid / PER_USER_RANGE;
    214         } else {
    215             return UserHandle.USER_SYSTEM;
    216         }
    217     }
    218 
    219     /** @hide */
    220     @UnsupportedAppUsage
    221     public static @UserIdInt int getCallingUserId() {
    222         return getUserId(Binder.getCallingUid());
    223     }
    224 
    225     /** @hide */
    226     public static @AppIdInt int getCallingAppId() {
    227         return getAppId(Binder.getCallingUid());
    228     }
    229 
    230     /** @hide */
    231     @SystemApi
    232     public static UserHandle of(@UserIdInt int userId) {
    233         return userId == USER_SYSTEM ? SYSTEM : new UserHandle(userId);
    234     }
    235 
    236     /**
    237      * Returns the uid that is composed from the userId and the appId.
    238      * @hide
    239      */
    240     @UnsupportedAppUsage
    241     public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {
    242         if (MU_ENABLED) {
    243             return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
    244         } else {
    245             return appId;
    246         }
    247     }
    248 
    249     /**
    250      * Returns the app id (or base uid) for a given uid, stripping out the user id from it.
    251      * @hide
    252      */
    253     @TestApi
    254     @SystemApi
    255     public static @AppIdInt int getAppId(int uid) {
    256         return uid % PER_USER_RANGE;
    257     }
    258 
    259     /**
    260      * Returns the gid shared between all apps with this userId.
    261      * @hide
    262      */
    263     public static int getUserGid(@UserIdInt int userId) {
    264         return getUid(userId, Process.SHARED_USER_GID);
    265     }
    266 
    267     /** @hide */
    268     public static int getSharedAppGid(int uid) {
    269         return getSharedAppGid(getUserId(uid), getAppId(uid));
    270     }
    271 
    272     /** @hide */
    273     public static int getSharedAppGid(int userId, int appId) {
    274         if (appId >= AID_APP_START && appId <= AID_APP_END) {
    275             return (appId - AID_APP_START) + AID_SHARED_GID_START;
    276         } else if (appId >= AID_ROOT && appId <= AID_APP_START) {
    277             return appId;
    278         } else {
    279             return -1;
    280         }
    281     }
    282 
    283     /**
    284      * Returns the app id for a given shared app gid. Returns -1 if the ID is invalid.
    285      * @hide
    286      */
    287     @UnsupportedAppUsage
    288     public static @AppIdInt int getAppIdFromSharedAppGid(int gid) {
    289         final int appId = getAppId(gid) + Process.FIRST_APPLICATION_UID
    290                 - Process.FIRST_SHARED_APPLICATION_GID;
    291         if (appId < 0 || appId >= Process.FIRST_SHARED_APPLICATION_GID) {
    292             return -1;
    293         }
    294         return appId;
    295     }
    296 
    297     /** @hide */
    298     public static int getCacheAppGid(int uid) {
    299         return getCacheAppGid(getUserId(uid), getAppId(uid));
    300     }
    301 
    302     /** @hide */
    303     public static int getCacheAppGid(int userId, int appId) {
    304         if (appId >= AID_APP_START && appId <= AID_APP_END) {
    305             return getUid(userId, (appId - AID_APP_START) + AID_CACHE_GID_START);
    306         } else {
    307             return -1;
    308         }
    309     }
    310 
    311     /**
    312      * Generate a text representation of the uid, breaking out its individual
    313      * components -- user, app, isolated, etc.
    314      * @hide
    315      */
    316     public static void formatUid(StringBuilder sb, int uid) {
    317         if (uid < Process.FIRST_APPLICATION_UID) {
    318             sb.append(uid);
    319         } else {
    320             sb.append('u');
    321             sb.append(getUserId(uid));
    322             final int appId = getAppId(uid);
    323             if (isIsolated(appId)) {
    324                 if (appId > Process.FIRST_ISOLATED_UID) {
    325                     sb.append('i');
    326                     sb.append(appId - Process.FIRST_ISOLATED_UID);
    327                 } else {
    328                     sb.append("ai");
    329                     sb.append(appId - Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
    330                 }
    331             } else if (appId >= Process.FIRST_APPLICATION_UID) {
    332                 sb.append('a');
    333                 sb.append(appId - Process.FIRST_APPLICATION_UID);
    334             } else {
    335                 sb.append('s');
    336                 sb.append(appId);
    337             }
    338         }
    339     }
    340 
    341     /**
    342      * Generate a text representation of the uid, breaking out its individual
    343      * components -- user, app, isolated, etc.
    344      * @hide
    345      */
    346     public static String formatUid(int uid) {
    347         StringBuilder sb = new StringBuilder();
    348         formatUid(sb, uid);
    349         return sb.toString();
    350     }
    351 
    352     /**
    353      * Generate a text representation of the uid, breaking out its individual
    354      * components -- user, app, isolated, etc.
    355      * @hide
    356      */
    357     public static void formatUid(PrintWriter pw, int uid) {
    358         if (uid < Process.FIRST_APPLICATION_UID) {
    359             pw.print(uid);
    360         } else {
    361             pw.print('u');
    362             pw.print(getUserId(uid));
    363             final int appId = getAppId(uid);
    364             if (isIsolated(appId)) {
    365                 if (appId > Process.FIRST_ISOLATED_UID) {
    366                     pw.print('i');
    367                     pw.print(appId - Process.FIRST_ISOLATED_UID);
    368                 } else {
    369                     pw.print("ai");
    370                     pw.print(appId - Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
    371                 }
    372             } else if (appId >= Process.FIRST_APPLICATION_UID) {
    373                 pw.print('a');
    374                 pw.print(appId - Process.FIRST_APPLICATION_UID);
    375             } else {
    376                 pw.print('s');
    377                 pw.print(appId);
    378             }
    379         }
    380     }
    381 
    382     /** @hide */
    383     public static @UserIdInt int parseUserArg(String arg) {
    384         int userId;
    385         if ("all".equals(arg)) {
    386             userId = UserHandle.USER_ALL;
    387         } else if ("current".equals(arg) || "cur".equals(arg)) {
    388             userId = UserHandle.USER_CURRENT;
    389         } else {
    390             try {
    391                 userId = Integer.parseInt(arg);
    392             } catch (NumberFormatException e) {
    393                 throw new IllegalArgumentException("Bad user number: " + arg);
    394             }
    395         }
    396         return userId;
    397     }
    398 
    399     /**
    400      * Returns the user id of the current process
    401      * @return user id of the current process
    402      * @hide
    403      */
    404     @SystemApi
    405     public static @UserIdInt int myUserId() {
    406         return getUserId(Process.myUid());
    407     }
    408 
    409     /**
    410      * Returns true if this UserHandle refers to the owner user; false otherwise.
    411      * @return true if this UserHandle refers to the owner user; false otherwise.
    412      * @hide
    413      * @deprecated please use {@link #isSystem()} or check for
    414      * {@link android.content.pm.UserInfo#isPrimary()}
    415      * {@link android.content.pm.UserInfo#isAdmin()} based on your particular use case.
    416      */
    417     @Deprecated
    418     @SystemApi
    419     public boolean isOwner() {
    420         return this.equals(OWNER);
    421     }
    422 
    423     /**
    424      * @return true if this UserHandle refers to the system user; false otherwise.
    425      * @hide
    426      */
    427     @SystemApi
    428     public boolean isSystem() {
    429         return this.equals(SYSTEM);
    430     }
    431 
    432     /** @hide */
    433     @UnsupportedAppUsage
    434     public UserHandle(int h) {
    435         mHandle = h;
    436     }
    437 
    438     /**
    439      * Returns the userId stored in this UserHandle.
    440      * @hide
    441      */
    442     @SystemApi
    443     @TestApi
    444     public @UserIdInt int getIdentifier() {
    445         return mHandle;
    446     }
    447 
    448     @Override
    449     public String toString() {
    450         return "UserHandle{" + mHandle + "}";
    451     }
    452 
    453     @Override
    454     public boolean equals(Object obj) {
    455         try {
    456             if (obj != null) {
    457                 UserHandle other = (UserHandle)obj;
    458                 return mHandle == other.mHandle;
    459             }
    460         } catch (ClassCastException e) {
    461         }
    462         return false;
    463     }
    464 
    465     @Override
    466     public int hashCode() {
    467         return mHandle;
    468     }
    469 
    470     public int describeContents() {
    471         return 0;
    472     }
    473 
    474     public void writeToParcel(Parcel out, int flags) {
    475         out.writeInt(mHandle);
    476     }
    477 
    478     /**
    479      * Write a UserHandle to a Parcel, handling null pointers.  Must be
    480      * read with {@link #readFromParcel(Parcel)}.
    481      *
    482      * @param h The UserHandle to be written.
    483      * @param out The Parcel in which the UserHandle will be placed.
    484      *
    485      * @see #readFromParcel(Parcel)
    486      */
    487     public static void writeToParcel(UserHandle h, Parcel out) {
    488         if (h != null) {
    489             h.writeToParcel(out, 0);
    490         } else {
    491             out.writeInt(USER_NULL);
    492         }
    493     }
    494 
    495     /**
    496      * Read a UserHandle from a Parcel that was previously written
    497      * with {@link #writeToParcel(UserHandle, Parcel)}, returning either
    498      * a null or new object as appropriate.
    499      *
    500      * @param in The Parcel from which to read the UserHandle
    501      * @return Returns a new UserHandle matching the previously written
    502      * object, or null if a null had been written.
    503      *
    504      * @see #writeToParcel(UserHandle, Parcel)
    505      */
    506     public static UserHandle readFromParcel(Parcel in) {
    507         int h = in.readInt();
    508         return h != USER_NULL ? new UserHandle(h) : null;
    509     }
    510 
    511     public static final @android.annotation.NonNull Parcelable.Creator<UserHandle> CREATOR
    512             = new Parcelable.Creator<UserHandle>() {
    513         public UserHandle createFromParcel(Parcel in) {
    514             return new UserHandle(in);
    515         }
    516 
    517         public UserHandle[] newArray(int size) {
    518             return new UserHandle[size];
    519         }
    520     };
    521 
    522     /**
    523      * Instantiate a new UserHandle from the data in a Parcel that was
    524      * previously written with {@link #writeToParcel(Parcel, int)}.  Note that you
    525      * must not use this with data written by
    526      * {@link #writeToParcel(UserHandle, Parcel)} since it is not possible
    527      * to handle a null UserHandle here.
    528      *
    529      * @param in The Parcel containing the previously written UserHandle,
    530      * positioned at the location in the buffer where it was written.
    531      */
    532     public UserHandle(Parcel in) {
    533         mHandle = in.readInt();
    534     }
    535 }
    536