blob: 20a13334e564ee004abbf178f49496eb92c1cfeb [file] [log] [blame]
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -08001/*
2** Copyright 2015, 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
17package com.android.server.wm;
18
Sudheer Shankadc589ac2016-11-10 15:30:17 -080019import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070020import android.app.ActivityTaskManager;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -070021import android.app.UriGrantsManager;
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080022import android.content.ClipData;
23import android.net.Uri;
24import android.os.Binder;
25import android.os.IBinder;
26import android.os.RemoteException;
27
Vladislav Kaznacheev377c3282016-04-20 14:22:23 -070028import com.android.internal.view.IDragAndDropPermissions;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -070029import com.android.server.LocalServices;
30import com.android.server.uri.UriGrantsManagerInternal;
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080031
32import java.util.ArrayList;
33
Vladislav Kaznacheev377c3282016-04-20 14:22:23 -070034class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub
35 implements IBinder.DeathRecipient {
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080036
37 private final int mSourceUid;
38 private final String mTargetPackage;
39 private final int mMode;
40 private final int mSourceUserId;
41 private final int mTargetUserId;
42
43 private final ArrayList<Uri> mUris = new ArrayList<Uri>();
44
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -080045 private IBinder mActivityToken = null;
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -080046 private IBinder mPermissionOwnerToken = null;
Vladislav Kaznacheev87c60d62016-07-21 15:25:12 -070047 private IBinder mTransientToken = null;
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080048
Vladislav Kaznacheev377c3282016-04-20 14:22:23 -070049 DragAndDropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode,
50 int sourceUserId, int targetUserId) {
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080051 mSourceUid = sourceUid;
52 mTargetPackage = targetPackage;
53 mMode = mode;
54 mSourceUserId = sourceUserId;
55 mTargetUserId = targetUserId;
56
57 clipData.collectUris(mUris);
58 }
59
60 @Override
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -080061 public void take(IBinder activityToken) throws RemoteException {
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -080062 if (mActivityToken != null || mPermissionOwnerToken != null) {
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080063 return;
64 }
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -080065 mActivityToken = activityToken;
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080066
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -080067 // Will throw if Activity is not found.
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070068 IBinder permissionOwner = ActivityTaskManager.getService().
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -080069 getUriPermissionOwnerForActivity(mActivityToken);
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080070
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -080071 doTake(permissionOwner);
72 }
73
74 private void doTake(IBinder permissionOwner) throws RemoteException {
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080075 long origId = Binder.clearCallingIdentity();
76 try {
77 for (int i = 0; i < mUris.size(); i++) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -070078 UriGrantsManager.getService().grantUriPermissionFromOwner(
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -080079 permissionOwner, mSourceUid, mTargetPackage, mUris.get(i), mMode,
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -080080 mSourceUserId, mTargetUserId);
81 }
82 } finally {
83 Binder.restoreCallingIdentity(origId);
84 }
85 }
86
87 @Override
Vladislav Kaznacheev87c60d62016-07-21 15:25:12 -070088 public void takeTransient(IBinder transientToken) throws RemoteException {
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -080089 if (mActivityToken != null || mPermissionOwnerToken != null) {
90 return;
91 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -070092 mPermissionOwnerToken = LocalServices.getService(UriGrantsManagerInternal.class)
93 .newUriPermissionOwner("drop");
Vladislav Kaznacheev87c60d62016-07-21 15:25:12 -070094 mTransientToken = transientToken;
95 mTransientToken.linkToDeath(this, 0);
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -080096
97 doTake(mPermissionOwnerToken);
98 }
99
100 @Override
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -0800101 public void release() throws RemoteException {
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -0800102 if (mActivityToken == null && mPermissionOwnerToken == null) {
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -0800103 return;
104 }
105
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -0800106 IBinder permissionOwner = null;
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -0800107 if (mActivityToken != null) {
108 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700109 permissionOwner = ActivityTaskManager.getService().
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -0800110 getUriPermissionOwnerForActivity(mActivityToken);
111 } catch (Exception e) {
112 // Activity is destroyed, permissions already revoked.
113 return;
114 } finally {
115 mActivityToken = null;
116 }
117 } else {
118 permissionOwner = mPermissionOwnerToken;
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -0800119 mPermissionOwnerToken = null;
Vladislav Kaznacheev87c60d62016-07-21 15:25:12 -0700120 mTransientToken.unlinkToDeath(this, 0);
121 mTransientToken = null;
Vladislav Kaznacheevb23a7572015-12-18 12:23:43 -0800122 }
123
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700124 UriGrantsManagerInternal ugm = LocalServices.getService(UriGrantsManagerInternal.class);
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -0800125 for (int i = 0; i < mUris.size(); ++i) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700126 ugm.revokeUriPermissionFromOwner(permissionOwner, mUris.get(i), mMode, mSourceUserId);
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -0800127 }
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -0800128 }
Vladislav Kaznacheevc14df8e2016-01-22 11:49:13 -0800129
130 @Override
131 public void binderDied() {
132 try {
133 release();
134 } catch (RemoteException e) {
135 // Cannot happen, local call.
136 }
137 }
Vladislav Kaznacheev9149d2b2015-12-15 12:16:28 -0800138}