Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20225978 authored by Nicolas Prevot's avatar Nicolas Prevot Committed by Android (Google) Code Review
Browse files

Merge "Resolving resources across users."

parents 515396a6 d85fc72f
Loading
Loading
Loading
Loading
+35 −17
Original line number Diff line number Diff line
@@ -1114,7 +1114,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            int pid = data.readInt();
            int uid = data.readInt();
            int mode = data.readInt();
            int res = checkUriPermission(uri, pid, uid, mode);
            int userId = data.readInt();
            int res = checkUriPermission(uri, pid, uid, mode, userId);
            reply.writeNoException();
            reply.writeInt(res);
            return true;
@@ -1139,7 +1140,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            String targetPkg = data.readString();
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int mode = data.readInt();
            grantUriPermission(app, targetPkg, uri, mode);
            int userId = data.readInt();
            grantUriPermission(app, targetPkg, uri, mode, userId);
            reply.writeNoException();
            return true;
        }
@@ -1150,7 +1152,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int mode = data.readInt();
            revokeUriPermission(app, uri, mode);
            int userId = data.readInt();
            revokeUriPermission(app, uri, mode, userId);
            reply.writeNoException();
            return true;
        }
@@ -1159,7 +1162,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            data.enforceInterface(IActivityManager.descriptor);
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int mode = data.readInt();
            takePersistableUriPermission(uri, mode);
            int userId = data.readInt();
            takePersistableUriPermission(uri, mode, userId);
            reply.writeNoException();
            return true;
        }
@@ -1168,7 +1172,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            data.enforceInterface(IActivityManager.descriptor);
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int mode = data.readInt();
            releasePersistableUriPermission(uri, mode);
            int userId = data.readInt();
            releasePersistableUriPermission(uri, mode, userId);
            reply.writeNoException();
            return true;
        }
@@ -1602,7 +1607,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            String targetPkg = data.readString();
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int mode = data.readInt();
            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode);
            int userId = data.readInt();
            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode, userId);
            reply.writeNoException();
            return true;
        }
@@ -1612,10 +1618,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            IBinder owner = data.readStrongBinder();
            Uri uri = null;
            if (data.readInt() != 0) {
                Uri.CREATOR.createFromParcel(data);
                uri = Uri.CREATOR.createFromParcel(data);
            }
            int mode = data.readInt();
            revokeUriPermissionFromOwner(owner, uri, mode);
            int userId = data.readInt();
            revokeUriPermissionFromOwner(owner, uri, mode, userId);
            reply.writeNoException();
            return true;
        }
@@ -1626,7 +1633,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            String targetPkg = data.readString();
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int modeFlags = data.readInt();
            int res = checkGrantUriPermission(callingUid, targetPkg, uri, modeFlags);
            int userId = data.readInt();
            int res = checkGrantUriPermission(callingUid, targetPkg, uri, modeFlags, userId);
            reply.writeNoException();
            reply.writeInt(res);
            return true;
@@ -3540,7 +3548,7 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
        return res;
    }
    public int checkUriPermission(Uri uri, int pid, int uid, int mode) 
    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
@@ -3549,6 +3557,7 @@ class ActivityManagerProxy implements IActivityManager
        data.writeInt(pid);
        data.writeInt(uid);
        data.writeInt(mode);
        data.writeInt(userId);
        mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        int res = reply.readInt();
@@ -3557,7 +3566,7 @@ class ActivityManagerProxy implements IActivityManager
        return res;
    }
    public void grantUriPermission(IApplicationThread caller, String targetPkg,
            Uri uri, int mode) throws RemoteException {
            Uri uri, int mode, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
@@ -3565,19 +3574,21 @@ class ActivityManagerProxy implements IActivityManager
        data.writeString(targetPkg);
        uri.writeToParcel(data, 0);
        data.writeInt(mode);
        data.writeInt(userId);
        mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }
    public void revokeUriPermission(IApplicationThread caller, Uri uri,
            int mode) throws RemoteException {
            int mode, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller.asBinder());
        uri.writeToParcel(data, 0);
        data.writeInt(mode);
        data.writeInt(userId);
        mRemote.transact(REVOKE_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
@@ -3585,12 +3596,14 @@ class ActivityManagerProxy implements IActivityManager
    }

    @Override
    public void takePersistableUriPermission(Uri uri, int mode) throws RemoteException {
    public void takePersistableUriPermission(Uri uri, int mode, int userId)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        uri.writeToParcel(data, 0);
        data.writeInt(mode);
        data.writeInt(userId);
        mRemote.transact(TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
@@ -3598,12 +3611,14 @@ class ActivityManagerProxy implements IActivityManager
    }

    @Override
    public void releasePersistableUriPermission(Uri uri, int mode) throws RemoteException {
    public void releasePersistableUriPermission(Uri uri, int mode, int userId)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        uri.writeToParcel(data, 0);
        data.writeInt(mode);
        data.writeInt(userId);
        mRemote.transact(RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
@@ -4157,7 +4172,7 @@ class ActivityManagerProxy implements IActivityManager
    }

    public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
            Uri uri, int mode) throws RemoteException {
            Uri uri, int mode, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4166,6 +4181,7 @@ class ActivityManagerProxy implements IActivityManager
        data.writeString(targetPkg);
        uri.writeToParcel(data, 0);
        data.writeInt(mode);
        data.writeInt(userId);
        mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
@@ -4173,7 +4189,7 @@ class ActivityManagerProxy implements IActivityManager
    }

    public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
            int mode) throws RemoteException {
            int mode, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4185,6 +4201,7 @@ class ActivityManagerProxy implements IActivityManager
            data.writeInt(0);
        }
        data.writeInt(mode);
        data.writeInt(userId);
        mRemote.transact(REVOKE_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
@@ -4192,7 +4209,7 @@ class ActivityManagerProxy implements IActivityManager
    }

    public int checkGrantUriPermission(int callingUid, String targetPkg,
            Uri uri, int modeFlags) throws RemoteException {
            Uri uri, int modeFlags, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4200,6 +4217,7 @@ class ActivityManagerProxy implements IActivityManager
        data.writeString(targetPkg);
        uri.writeToParcel(data, 0);
        data.writeInt(modeFlags);
        data.writeInt(userId);
        mRemote.transact(CHECK_GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
        reply.readException();
        int res = reply.readInt();
+25 −8
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.internal.util.Preconditions;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
@@ -1818,8 +1819,8 @@ class ContextImpl extends Context {
    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
         try {
            ActivityManagerNative.getDefault().grantUriPermission(
                    mMainThread.getApplicationThread(), toPackage, uri,
                    modeFlags);
                    mMainThread.getApplicationThread(), toPackage,
                    ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
        } catch (RemoteException e) {
        }
    }
@@ -1828,8 +1829,8 @@ class ContextImpl extends Context {
    public void revokeUriPermission(Uri uri, int modeFlags) {
         try {
            ActivityManagerNative.getDefault().revokeUriPermission(
                    mMainThread.getApplicationThread(), uri,
                    modeFlags);
                    mMainThread.getApplicationThread(),
                    ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
        } catch (RemoteException e) {
        }
    }
@@ -1838,12 +1839,17 @@ class ContextImpl extends Context {
    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
        try {
            return ActivityManagerNative.getDefault().checkUriPermission(
                    uri, pid, uid, modeFlags);
                    ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
                    resolveUserId(uri));
        } catch (RemoteException e) {
            return PackageManager.PERMISSION_DENIED;
        }
    }

    private int resolveUserId(Uri uri) {
        return ContentProvider.getUserIdFromUri(uri, getUserId());
    }

    @Override
    public int checkCallingUriPermission(Uri uri, int modeFlags) {
        int pid = Binder.getCallingPid();
@@ -2280,12 +2286,16 @@ class ContextImpl extends Context {

        @Override
        protected IContentProvider acquireProvider(Context context, String auth) {
            return mMainThread.acquireProvider(context, auth, mUser.getIdentifier(), true);
            return mMainThread.acquireProvider(context,
                    ContentProvider.getAuthorityWithoutUserId(auth),
                    resolveUserIdFromAuthority(auth), true);
        }

        @Override
        protected IContentProvider acquireExistingProvider(Context context, String auth) {
            return mMainThread.acquireExistingProvider(context, auth, mUser.getIdentifier(), true);
            return mMainThread.acquireExistingProvider(context,
                    ContentProvider.getAuthorityWithoutUserId(auth),
                    resolveUserIdFromAuthority(auth), true);
        }

        @Override
@@ -2295,7 +2305,9 @@ class ContextImpl extends Context {

        @Override
        protected IContentProvider acquireUnstableProvider(Context c, String auth) {
            return mMainThread.acquireProvider(c, auth, mUser.getIdentifier(), false);
            return mMainThread.acquireProvider(c,
                    ContentProvider.getAuthorityWithoutUserId(auth),
                    resolveUserIdFromAuthority(auth), false);
        }

        @Override
@@ -2312,5 +2324,10 @@ class ContextImpl extends Context {
        public void appNotRespondingViaProvider(IContentProvider icp) {
            mMainThread.appNotRespondingViaProvider(icp.asBinder());
        }

        /** @hide */
        protected int resolveUserIdFromAuthority(String auth) {
            return ContentProvider.getUserIdFromAuthority(auth, mUser.getIdentifier());
        }
    }
}
+13 −11
Original line number Diff line number Diff line
@@ -210,14 +210,16 @@ public interface IActivityManager extends IInterface {
    public int checkPermission(String permission, int pid, int uid)
            throws RemoteException;

    public int checkUriPermission(Uri uri, int pid, int uid, int mode)
    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId)
            throws RemoteException;
    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
            int mode, int userId) throws RemoteException;
    public void revokeUriPermission(IApplicationThread caller, Uri uri, int mode, int userId)
            throws RemoteException;
    public void takePersistableUriPermission(Uri uri, int modeFlags, int userId)
            throws RemoteException;
    public void releasePersistableUriPermission(Uri uri, int modeFlags, int userId)
            throws RemoteException;
    public void grantUriPermission(IApplicationThread caller, String targetPkg,
            Uri uri, int mode) throws RemoteException;
    public void revokeUriPermission(IApplicationThread caller, Uri uri,
            int mode) throws RemoteException;
    public void takePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
    public void releasePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
    public ParceledListSlice<UriPermission> getPersistedUriPermissions(
            String packageName, boolean incoming) throws RemoteException;

@@ -323,12 +325,12 @@ public interface IActivityManager extends IInterface {
    
    public IBinder newUriPermissionOwner(String name) throws RemoteException;
    public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
            Uri uri, int mode) throws RemoteException;
            Uri uri, int mode, int userId) throws RemoteException;
    public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
            int mode) throws RemoteException;
            int mode, int userId) throws RemoteException;

    public int checkGrantUriPermission(int callingUid, String targetPkg,
            Uri uri, int modeFlags) throws RemoteException;
    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
            int modeFlags, int userId) throws RemoteException;

    // Cause the specified process to dump the specified heap.
    public boolean dumpHeap(String process, int userId, boolean managed, String path,
+20 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.content;

import static android.content.ContentProvider.maybeAddUserId;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -186,7 +187,7 @@ public class ClipData implements Parcelable {
        final CharSequence mText;
        final String mHtmlText;
        final Intent mIntent;
        final Uri mUri;
        Uri mUri;

        /**
         * Create an Item consisting of a single block of (possibly styled) text.
@@ -809,6 +810,24 @@ public class ClipData implements Parcelable {
        }
    }

    /**
     * Prepare this {@link ClipData} to leave an app process.
     *
     * @hide
     */
    public void prepareToLeaveUser(int userId) {
        final int size = mItems.size();
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mIntent != null) {
                item.mIntent.prepareToLeaveUser(userId);
            }
            if (item.mUri != null) {
                item.mUri = maybeAddUserId(item.mUri, userId);
            }
        }
    }

    @Override
    public String toString() {
        StringBuilder b = new StringBuilder(128);
+108 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
import android.text.TextUtils;

import java.io.File;
import java.io.FileDescriptor;
@@ -195,6 +196,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
                return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
                        CancellationSignal.fromTransport(cancellationSignal));
            }
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.query(
@@ -207,6 +209,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {

        @Override
        public String getType(Uri uri) {
            uri = getUriWithoutUserId(uri);
            return ContentProvider.this.getType(uri);
        }

@@ -215,9 +218,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                return rejectInsert(uri, initialValues);
            }
            int userId = getUserIdFromUri(uri);
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.insert(uri, initialValues);
                return maybeAddUserId(ContentProvider.this.insert(uri, initialValues), userId);
            } finally {
                setCallingPackage(original);
            }
@@ -228,6 +233,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                return 0;
            }
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.bulkInsert(uri, initialValues);
@@ -240,24 +246,39 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
        public ContentProviderResult[] applyBatch(String callingPkg,
                ArrayList<ContentProviderOperation> operations)
                throws OperationApplicationException {
            for (ContentProviderOperation operation : operations) {
            int numOperations = operations.size();
            final int[] userIds = new int[numOperations];
            for (int i = 0; i < numOperations; i++) {
                ContentProviderOperation operation = operations.get(i);
                userIds[i] = getUserIdFromUri(operation.getUri());
                if (operation.isReadOperation()) {
                    if (enforceReadPermission(callingPkg, operation.getUri())
                            != AppOpsManager.MODE_ALLOWED) {
                        throw new OperationApplicationException("App op not allowed", 0);
                    }
                }

                if (operation.isWriteOperation()) {
                    if (enforceWritePermission(callingPkg, operation.getUri())
                            != AppOpsManager.MODE_ALLOWED) {
                        throw new OperationApplicationException("App op not allowed", 0);
                    }
                }
                if (userIds[i] != UserHandle.USER_CURRENT) {
                    // Removing the user id from the uri.
                    operation = new ContentProviderOperation(operation, true);
                }
                operations.set(i, operation);
            }
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.applyBatch(operations);
                ContentProviderResult[] results = ContentProvider.this.applyBatch(operations);
                for (int i = 0; i < results.length ; i++) {
                    if (userIds[i] != UserHandle.USER_CURRENT) {
                        // Adding the userId to the uri.
                        results[i] = new ContentProviderResult(results[i], userIds[i]);
                    }
                }
                return results;
            } finally {
                setCallingPackage(original);
            }
@@ -268,6 +289,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                return 0;
            }
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.delete(uri, selection, selectionArgs);
@@ -282,6 +304,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                return 0;
            }
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.update(uri, values, selection, selectionArgs);
@@ -295,6 +318,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                throws FileNotFoundException {
            enforceFilePermission(callingPkg, uri, mode);
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.openFile(
@@ -309,6 +333,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                throws FileNotFoundException {
            enforceFilePermission(callingPkg, uri, mode);
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.openAssetFile(
@@ -330,6 +355,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {

        @Override
        public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
            uri = getUriWithoutUserId(uri);
            return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
        }

@@ -337,6 +363,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
        public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
                Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
            enforceFilePermission(callingPkg, uri, "r");
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.openTypedAssetFile(
@@ -356,9 +383,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                return null;
            }
            int userId = getUserIdFromUri(uri);
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.canonicalize(uri);
                return maybeAddUserId(ContentProvider.this.canonicalize(uri), userId);
            } finally {
                setCallingPackage(original);
            }
@@ -369,9 +398,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                return null;
            }
            int userId = getUserIdFromUri(uri);
            uri = getUriWithoutUserId(uri);
            final String original = setCallingPackage(callingPkg);
            try {
                return ContentProvider.this.uncanonicalize(uri);
                return maybeAddUserId(ContentProvider.this.uncanonicalize(uri), userId);
            } finally {
                setCallingPackage(original);
            }
@@ -1680,4 +1711,75 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        writer.println("nothing to dump");
    }

    /** @hide */
    public static int getUserIdFromAuthority(String auth, int defaultUserId) {
        if (auth == null) return defaultUserId;
        int end = auth.indexOf('@');
        if (end == -1) return defaultUserId;
        String userIdString = auth.substring(0, end);
        try {
            return Integer.parseInt(userIdString);
        } catch (NumberFormatException e) {
            Log.w(TAG, "Error parsing userId.", e);
            return UserHandle.USER_NULL;
        }
    }

    /** @hide */
    public static int getUserIdFromAuthority(String auth) {
        return getUserIdFromAuthority(auth, UserHandle.USER_CURRENT);
    }

    /** @hide */
    public static int getUserIdFromUri(Uri uri, int defaultUserId) {
        if (uri == null) return defaultUserId;
        return getUserIdFromAuthority(uri.getAuthority(), defaultUserId);
    }

    /** @hide */
    public static int getUserIdFromUri(Uri uri) {
        return getUserIdFromUri(uri, UserHandle.USER_CURRENT);
    }

    /**
     * Removes userId part from authority string. Expects format:
     * userId@some.authority
     * If there is no userId in the authority, it symply returns the argument
     * @hide
     */
    public static String getAuthorityWithoutUserId(String auth) {
        if (auth == null) return null;
        int end = auth.indexOf('@');
        return auth.substring(end+1);
    }

    /** @hide */
    public static Uri getUriWithoutUserId(Uri uri) {
        if (uri == null) return null;
        Uri.Builder builder = uri.buildUpon();
        builder.authority(getAuthorityWithoutUserId(uri.getAuthority()));
        return builder.build();
    }

    /** @hide */
    public static boolean uriHasUserId(Uri uri) {
        if (uri == null) return false;
        return !TextUtils.isEmpty(uri.getUserInfo());
    }

    /** @hide */
    public static Uri maybeAddUserId(Uri uri, int userId) {
        if (uri == null) return null;
        if (userId != UserHandle.USER_CURRENT
                && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
            if (!uriHasUserId(uri)) {
                //We don't add the user Id if there's already one
                Uri.Builder builder = uri.buildUpon();
                builder.encodedAuthority("" + userId + "@" + uri.getEncodedAuthority());
                return builder.build();
            }
        }
        return uri;
    }
}
Loading