Home | History | Annotate | Download | only in job
      1 /*
      2  * Copyright (C) 2017 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 com.android.server.job;
     18 
     19 import android.app.IActivityManager;
     20 import android.content.ClipData;
     21 import android.content.ContentProvider;
     22 import android.content.Intent;
     23 import android.net.Uri;
     24 import android.os.IBinder;
     25 import android.os.RemoteException;
     26 import android.os.UserHandle;
     27 import android.util.Slog;
     28 import android.util.proto.ProtoOutputStream;
     29 
     30 import java.io.PrintWriter;
     31 import java.util.ArrayList;
     32 
     33 public final class GrantedUriPermissions {
     34     private final int mGrantFlags;
     35     private final int mSourceUserId;
     36     private final String mTag;
     37     private final IBinder mPermissionOwner;
     38     private final ArrayList<Uri> mUris = new ArrayList<>();
     39 
     40     private GrantedUriPermissions(IActivityManager am, int grantFlags, int uid, String tag)
     41             throws RemoteException {
     42         mGrantFlags = grantFlags;
     43         mSourceUserId = UserHandle.getUserId(uid);
     44         mTag = tag;
     45         mPermissionOwner = am.newUriPermissionOwner("job: " + tag);
     46     }
     47 
     48     public void revoke(IActivityManager am) {
     49         for (int i = mUris.size()-1; i >= 0; i--) {
     50             try {
     51                 am.revokeUriPermissionFromOwner(mPermissionOwner, mUris.get(i),
     52                         mGrantFlags, mSourceUserId);
     53             } catch (RemoteException e) {
     54             }
     55         }
     56         mUris.clear();
     57     }
     58 
     59     public static boolean checkGrantFlags(int grantFlags) {
     60         return (grantFlags & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION
     61                 |Intent.FLAG_GRANT_READ_URI_PERMISSION)) != 0;
     62     }
     63 
     64     public static GrantedUriPermissions createFromIntent(IActivityManager am, Intent intent,
     65             int sourceUid, String targetPackage, int targetUserId, String tag) {
     66         int grantFlags = intent.getFlags();
     67         if (!checkGrantFlags(grantFlags)) {
     68             return null;
     69         }
     70 
     71         GrantedUriPermissions perms = null;
     72 
     73         Uri data = intent.getData();
     74         if (data != null) {
     75             perms = grantUri(am, data, sourceUid, targetPackage, targetUserId, grantFlags, tag,
     76                     perms);
     77         }
     78 
     79         ClipData clip = intent.getClipData();
     80         if (clip != null) {
     81             perms = grantClip(am, clip, sourceUid, targetPackage, targetUserId, grantFlags, tag,
     82                     perms);
     83         }
     84 
     85         return perms;
     86     }
     87 
     88     public static GrantedUriPermissions createFromClip(IActivityManager am, ClipData clip,
     89             int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag) {
     90         if (!checkGrantFlags(grantFlags)) {
     91             return null;
     92         }
     93         GrantedUriPermissions perms = null;
     94         if (clip != null) {
     95             perms = grantClip(am, clip, sourceUid, targetPackage, targetUserId, grantFlags,
     96                     tag, perms);
     97         }
     98         return perms;
     99     }
    100 
    101     private static GrantedUriPermissions grantClip(IActivityManager am, ClipData clip,
    102             int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag,
    103             GrantedUriPermissions curPerms) {
    104         final int N = clip.getItemCount();
    105         for (int i = 0; i < N; i++) {
    106             curPerms = grantItem(am, clip.getItemAt(i), sourceUid, targetPackage, targetUserId,
    107                     grantFlags, tag, curPerms);
    108         }
    109         return curPerms;
    110     }
    111 
    112     private static GrantedUriPermissions grantUri(IActivityManager am, Uri uri,
    113             int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag,
    114             GrantedUriPermissions curPerms) {
    115         try {
    116             int sourceUserId = ContentProvider.getUserIdFromUri(uri,
    117                     UserHandle.getUserId(sourceUid));
    118             uri = ContentProvider.getUriWithoutUserId(uri);
    119             if (curPerms == null) {
    120                 curPerms = new GrantedUriPermissions(am, grantFlags, sourceUid, tag);
    121             }
    122             am.grantUriPermissionFromOwner(curPerms.mPermissionOwner, sourceUid, targetPackage,
    123                     uri, grantFlags, sourceUserId, targetUserId);
    124             curPerms.mUris.add(uri);
    125         } catch (RemoteException e) {
    126             Slog.e("JobScheduler", "AM dead");
    127         }
    128         return curPerms;
    129     }
    130 
    131     private static GrantedUriPermissions grantItem(IActivityManager am, ClipData.Item item,
    132             int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag,
    133             GrantedUriPermissions curPerms) {
    134         if (item.getUri() != null) {
    135             curPerms = grantUri(am, item.getUri(), sourceUid, targetPackage, targetUserId,
    136                     grantFlags, tag, curPerms);
    137         }
    138         Intent intent = item.getIntent();
    139         if (intent != null && intent.getData() != null) {
    140             curPerms = grantUri(am, intent.getData(), sourceUid, targetPackage, targetUserId,
    141                     grantFlags, tag, curPerms);
    142         }
    143         return curPerms;
    144     }
    145 
    146     // Dumpsys infrastructure
    147     public void dump(PrintWriter pw, String prefix) {
    148         pw.print(prefix); pw.print("mGrantFlags=0x"); pw.print(Integer.toHexString(mGrantFlags));
    149         pw.print(" mSourceUserId="); pw.println(mSourceUserId);
    150         pw.print(prefix); pw.print("mTag="); pw.println(mTag);
    151         pw.print(prefix); pw.print("mPermissionOwner="); pw.println(mPermissionOwner);
    152         for (int i = 0; i < mUris.size(); i++) {
    153             pw.print(prefix); pw.print("#"); pw.print(i); pw.print(": ");
    154             pw.println(mUris.get(i));
    155         }
    156     }
    157 
    158     public void dump(ProtoOutputStream proto, long fieldId) {
    159         final long token = proto.start(fieldId);
    160 
    161         proto.write(GrantedUriPermissionsDumpProto.FLAGS, mGrantFlags);
    162         proto.write(GrantedUriPermissionsDumpProto.SOURCE_USER_ID, mSourceUserId);
    163         proto.write(GrantedUriPermissionsDumpProto.TAG, mTag);
    164         proto.write(GrantedUriPermissionsDumpProto.PERMISSION_OWNER, mPermissionOwner.toString());
    165         for (int i = 0; i < mUris.size(); i++) {
    166             Uri u = mUris.get(i);
    167             if (u != null) {
    168                 proto.write(GrantedUriPermissionsDumpProto.URIS, u.toString());
    169             }
    170         }
    171 
    172         proto.end(token);
    173     }
    174 }
    175