1342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn/* 2342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * Copyright (C) 2017 The Android Open Source Project 3342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * 4342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * you may not use this file except in compliance with the License. 6342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * You may obtain a copy of the License at 7342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * 8342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * 10342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * Unless required by applicable law or agreed to in writing, software 11342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * See the License for the specific language governing permissions and 14342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn * limitations under the License 15342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn */ 16342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 17342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornpackage com.android.server.job; 18342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 19342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.app.IActivityManager; 20342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.content.ClipData; 21342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.content.ContentProvider; 22342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.content.Intent; 23342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.net.Uri; 24342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.os.IBinder; 25342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.os.RemoteException; 26342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.os.UserHandle; 27342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport android.util.Slog; 28342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 29342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport java.io.PrintWriter; 30342e6037109a53830277d8de6ecf0e39578c143cDianne Hackbornimport java.util.ArrayList; 31342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 326466c1cc5efc4ff05fabdd670cf78a6a7ca45afbDianne Hackbornpublic final class GrantedUriPermissions { 33342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private final int mGrantFlags; 34342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private final int mSourceUserId; 35342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private final String mTag; 36342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private final IBinder mPermissionOwner; 37342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private final ArrayList<Uri> mUris = new ArrayList<>(); 38342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 39342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private GrantedUriPermissions(IActivityManager am, int grantFlags, int uid, String tag) 40342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn throws RemoteException { 41342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn mGrantFlags = grantFlags; 42342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn mSourceUserId = UserHandle.getUserId(uid); 43342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn mTag = tag; 44342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn mPermissionOwner = am.newUriPermissionOwner("job: " + tag); 45342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 46342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 47342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn public void revoke(IActivityManager am) { 48342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn for (int i = mUris.size()-1; i >= 0; i--) { 49342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn try { 50342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn am.revokeUriPermissionFromOwner(mPermissionOwner, mUris.get(i), 51342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn mGrantFlags, mSourceUserId); 52342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } catch (RemoteException e) { 53342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 54342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 55342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn mUris.clear(); 56342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 57342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 58342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn public static boolean checkGrantFlags(int grantFlags) { 59342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return (grantFlags & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION 60342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn |Intent.FLAG_GRANT_READ_URI_PERMISSION)) != 0; 61342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 62342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 63342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn public static GrantedUriPermissions createFromIntent(IActivityManager am, Intent intent, 64342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn int sourceUid, String targetPackage, int targetUserId, String tag) { 65342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn int grantFlags = intent.getFlags(); 66342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (!checkGrantFlags(grantFlags)) { 67342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return null; 68342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 69342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 70342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn GrantedUriPermissions perms = null; 71342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 72342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn Uri data = intent.getData(); 73342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (data != null) { 74342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn perms = grantUri(am, data, sourceUid, targetPackage, targetUserId, grantFlags, tag, 75342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn perms); 76342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 77342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 78342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn ClipData clip = intent.getClipData(); 79342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (clip != null) { 80342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn perms = grantClip(am, clip, sourceUid, targetPackage, targetUserId, grantFlags, tag, 81342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn perms); 82342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 83342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 84342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return perms; 85342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 86342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 87342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn public static GrantedUriPermissions createFromClip(IActivityManager am, ClipData clip, 88342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag) { 89342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (!checkGrantFlags(grantFlags)) { 90342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return null; 91342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 92342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn GrantedUriPermissions perms = null; 93342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (clip != null) { 94342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn perms = grantClip(am, clip, sourceUid, targetPackage, targetUserId, grantFlags, 95342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn tag, perms); 96342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 97342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return perms; 98342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 99342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 100342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private static GrantedUriPermissions grantClip(IActivityManager am, ClipData clip, 101342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag, 102342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn GrantedUriPermissions curPerms) { 103342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn final int N = clip.getItemCount(); 104342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn for (int i = 0; i < N; i++) { 105342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn curPerms = grantItem(am, clip.getItemAt(i), sourceUid, targetPackage, targetUserId, 106342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn grantFlags, tag, curPerms); 107342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 108342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return curPerms; 109342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 110342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 111342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private static GrantedUriPermissions grantUri(IActivityManager am, Uri uri, 112342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag, 113342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn GrantedUriPermissions curPerms) { 114342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn try { 115342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn int sourceUserId = ContentProvider.getUserIdFromUri(uri, 116342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn UserHandle.getUserId(sourceUid)); 117342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn uri = ContentProvider.getUriWithoutUserId(uri); 118342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (curPerms == null) { 119342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn curPerms = new GrantedUriPermissions(am, grantFlags, sourceUid, tag); 120342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 121342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn am.grantUriPermissionFromOwner(curPerms.mPermissionOwner, sourceUid, targetPackage, 122342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn uri, grantFlags, sourceUserId, targetUserId); 123342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn curPerms.mUris.add(uri); 124342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } catch (RemoteException e) { 125342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn Slog.e("JobScheduler", "AM dead"); 126342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 127342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return curPerms; 128342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 129342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 130342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn private static GrantedUriPermissions grantItem(IActivityManager am, ClipData.Item item, 131342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag, 132342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn GrantedUriPermissions curPerms) { 133342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (item.getUri() != null) { 134342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn curPerms = grantUri(am, item.getUri(), sourceUid, targetPackage, targetUserId, 135342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn grantFlags, tag, curPerms); 136342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 137342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn Intent intent = item.getIntent(); 138342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn if (intent != null && intent.getData() != null) { 139342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn curPerms = grantUri(am, intent.getData(), sourceUid, targetPackage, targetUserId, 140342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn grantFlags, tag, curPerms); 141342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 142342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn return curPerms; 143342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 144342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn 145342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn // Dumpsys infrastructure 146342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn public void dump(PrintWriter pw, String prefix) { 147342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn pw.print(prefix); pw.print("mGrantFlags=0x"); pw.print(Integer.toHexString(mGrantFlags)); 148342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn pw.print(" mSourceUserId="); pw.println(mSourceUserId); 149342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn pw.print(prefix); pw.print("mTag="); pw.println(mTag); 150342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn pw.print(prefix); pw.print("mPermissionOwner="); pw.println(mPermissionOwner); 151342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn for (int i = 0; i < mUris.size(); i++) { 152342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn pw.print(prefix); pw.print("#"); pw.print(i); pw.print(": "); 153342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn pw.println(mUris.get(i)); 154342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 155342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn } 156342e6037109a53830277d8de6ecf0e39578c143cDianne Hackborn} 157