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