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.ActivityManagerNative; 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 = ActivityManagerNative.getDefault() 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 ActivityManagerNative.getDefault().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 ActivityManagerNative.getDefault().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