Home | History | Annotate | Download | only in server
      1 /*
      2 ** Copyright 2016, 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;
     18 
     19 import android.annotation.NonNull;
     20 import android.annotation.UserIdInt;
     21 import android.app.ActivityManager;
     22 import android.content.Intent;
     23 import android.net.Uri;
     24 import android.os.Binder;
     25 import android.os.IBinder;
     26 import android.os.RemoteException;
     27 
     28 import com.android.internal.annotations.GuardedBy;
     29 import com.android.internal.inputmethod.IInputContentUriToken;
     30 
     31 final class InputContentUriTokenHandler extends IInputContentUriToken.Stub {
     32 
     33     @NonNull
     34     private final Uri mUri;
     35     private final int mSourceUid;
     36     @NonNull
     37     private final String mTargetPackage;
     38     @UserIdInt
     39     private final int mSourceUserId;
     40     @UserIdInt
     41     private final int mTargetUserId;
     42 
     43     private final Object mLock = new Object();
     44 
     45     @GuardedBy("mLock")
     46     private IBinder mPermissionOwnerToken = null;
     47 
     48     InputContentUriTokenHandler(@NonNull Uri contentUri, int sourceUid,
     49             @NonNull String targetPackage, @UserIdInt int sourceUserId,
     50             @UserIdInt int targetUserId) {
     51         mUri = contentUri;
     52         mSourceUid = sourceUid;
     53         mTargetPackage = targetPackage;
     54         mSourceUserId = sourceUserId;
     55         mTargetUserId = targetUserId;
     56     }
     57 
     58     @Override
     59     public void take() {
     60         synchronized (mLock) {
     61             if (mPermissionOwnerToken != null) {
     62                 // Permission is already granted.
     63                 return;
     64             }
     65 
     66             try {
     67                 mPermissionOwnerToken = ActivityManager.getService()
     68                         .newUriPermissionOwner("InputContentUriTokenHandler");
     69             } catch (RemoteException e) {
     70                 e.rethrowFromSystemServer();
     71             }
     72 
     73             doTakeLocked(mPermissionOwnerToken);
     74         }
     75     }
     76 
     77     private void doTakeLocked(@NonNull IBinder permissionOwner) {
     78         long origId = Binder.clearCallingIdentity();
     79         try {
     80             try {
     81                 ActivityManager.getService().grantUriPermissionFromOwner(
     82                         permissionOwner, mSourceUid, mTargetPackage, mUri,
     83                         Intent.FLAG_GRANT_READ_URI_PERMISSION, mSourceUserId, mTargetUserId);
     84             } catch (RemoteException e) {
     85                 e.rethrowFromSystemServer();
     86             }
     87         } finally {
     88             Binder.restoreCallingIdentity(origId);
     89         }
     90     }
     91 
     92     @Override
     93     public void release() {
     94         synchronized (mLock) {
     95             if (mPermissionOwnerToken == null) {
     96                 return;
     97             }
     98             try {
     99                 ActivityManager.getService().revokeUriPermissionFromOwner(
    100                         mPermissionOwnerToken, mUri,
    101                         Intent.FLAG_GRANT_READ_URI_PERMISSION, mSourceUserId);
    102             } catch (RemoteException e) {
    103                 e.rethrowFromSystemServer();
    104             } finally {
    105                 mPermissionOwnerToken = null;
    106             }
    107         }
    108     }
    109 
    110     /**
    111      * {@inheritDoc}
    112      */
    113     @Override
    114     protected void finalize() throws Throwable {
    115         try {
    116             release();
    117         } finally {
    118             super.finalize();
    119         }
    120     }
    121 }
    122