ClipboardService.java revision ad70bc6c310f54d4810e67b49e7881c1f33a1d83
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1730f8eb472e44228069c2ffb8bd0b43213edbf04eAmith Yamasanipackage com.android.server.clipboard; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.app.ActivityManagerNative; 20ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tateimport android.app.AppGlobals; 21efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackbornimport android.app.AppOpsManager; 2290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.app.IActivityManager; 231040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackbornimport android.content.ClipData; 241040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackbornimport android.content.ClipDescription; 25d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevotimport android.content.ContentProvider; 269f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.content.IClipboard; 279f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.content.IOnPrimaryClipChangedListener; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 2990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.content.Intent; 30ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tateimport android.content.pm.IPackageManager; 3190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.content.pm.PackageInfo; 3290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.content.pm.PackageManager; 33f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevotimport android.content.pm.UserInfo; 3490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.net.Uri; 3590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.os.Binder; 3690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.os.IBinder; 37f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevotimport android.os.IUserManager; 3890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.os.Parcel; 3990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.os.Process; 409f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.RemoteCallbackList; 419f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.RemoteException; 42f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevotimport android.os.ServiceManager; 43f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 44f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevotimport android.os.UserManager; 4590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport android.util.Slog; 46e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasaniimport android.util.SparseArray; 4790f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 48ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shankaimport com.android.server.SystemService; 49ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 5090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackbornimport java.util.HashSet; 51f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevotimport java.util.List; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implementation of the clipboard for copy and paste. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 56ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shankapublic class ClipboardService extends SystemService { 57e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 58e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani private static final String TAG = "ClipboardService"; 59e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 6090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final IActivityManager mAm; 61f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot private final IUserManager mUm; 6290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final PackageManager mPm; 63efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn private final AppOpsManager mAppOps; 6490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final IBinder mPermissionOwner; 6590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 66ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka private final SparseArray<PerUserClipboard> mClipboards = new SparseArray<>(); 67ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 68ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka /** 69ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka * Instantiates the clipboard. 70ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka */ 71ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public ClipboardService(Context context) { 72ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka super(context); 73ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 74ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka mAm = ActivityManagerNative.getDefault(); 75ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka mPm = getContext().getPackageManager(); 76ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka mUm = (IUserManager) ServiceManager.getService(Context.USER_SERVICE); 77ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); 78ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka IBinder permOwner = null; 79ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka try { 80ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka permOwner = mAm.newUriPermissionOwner("clipboard"); 81ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } catch (RemoteException e) { 82ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka Slog.w("clipboard", "AM dead", e); 83ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 84ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka mPermissionOwner = permOwner; 85ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 86ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 87ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 88ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public void onStart() { 89ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka publishBinderService(Context.CLIPBOARD_SERVICE, new ClipboardImpl()); 90ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 91ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 92ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 93ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public void onCleanupUser(int userId) { 94ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (mClipboards) { 95ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka mClipboards.remove(userId); 96ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 97ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 98ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 99efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn private class ListenerInfo { 100efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn final int mUid; 101efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn final String mPackageName; 102efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn ListenerInfo(int uid, String packageName) { 103efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn mUid = uid; 104efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn mPackageName = packageName; 105efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn } 106efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn } 107efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn 108e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani private class PerUserClipboard { 109e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani final int userId; 110e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 111e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani final RemoteCallbackList<IOnPrimaryClipChangedListener> primaryClipListeners 112e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani = new RemoteCallbackList<IOnPrimaryClipChangedListener>(); 113e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 114e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani ClipData primaryClip; 115e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 116e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani final HashSet<String> activePermissionOwners 117e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani = new HashSet<String>(); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 119e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani PerUserClipboard(int userId) { 120e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani this.userId = userId; 121e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 122e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 12390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 124ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka private class ClipboardImpl extends IClipboard.Stub { 125ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 126ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 127ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka throws RemoteException { 128ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka try { 129ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return super.onTransact(code, data, reply, flags); 130ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } catch (RuntimeException e) { 131ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (!(e instanceof SecurityException)) { 132ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka Slog.wtf("clipboard", "Exception: ", e); 133ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 134ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka throw e; 135ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 13690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 13790f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 138e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 139ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 140ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public void setPrimaryClip(ClipData clip, String callingPackage) { 141ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (this) { 142ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (clip != null && clip.getItemCount() <= 0) { 143ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka throw new IllegalArgumentException("No items"); 144ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 145ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka final int callingUid = Binder.getCallingUid(); 146ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, callingUid, 147ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka callingPackage) != AppOpsManager.MODE_ALLOWED) { 148ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return; 149ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 150ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka checkDataOwnerLocked(clip, callingUid); 151ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka final int userId = UserHandle.getUserId(callingUid); 152ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka PerUserClipboard clipboard = getClipboard(userId); 153ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka revokeUris(clipboard); 154ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka setPrimaryClipInternal(clipboard, clip); 155ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka List<UserInfo> related = getRelatedProfiles(userId); 156ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (related != null) { 157ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka int size = related.size(); 158ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (size > 1) { // Related profiles list include the current profile. 159ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka boolean canCopy = false; 160ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka try { 161ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka canCopy = !mUm.getUserRestrictions(userId).getBoolean( 162ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); 163ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } catch (RemoteException e) { 164ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka Slog.e(TAG, "Remote Exception calling UserManager: " + e); 165ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 166ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka // Copy clip data to related users if allowed. If disallowed, then remove 167ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka // primary clip in related users to prevent pasting stale content. 168ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (!canCopy) { 169ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka clip = null; 170ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } else { 171ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka // We want to fix the uris of the related user's clip without changing the 172ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka // uris of the current user's clip. 173ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka // So, copy the ClipData, and then copy all the items, so that nothing 174ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka // is shared in memmory. 175ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka clip = new ClipData(clip); 176ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka for (int i = clip.getItemCount() - 1; i >= 0; i--) { 177ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka clip.setItemAt(i, new ClipData.Item(clip.getItemAt(i))); 178ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 179ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka clip.fixUrisLight(userId); 180ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 181ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka for (int i = 0; i < size; i++) { 182ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka int id = related.get(i).id; 183ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (id != userId) { 184ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka setPrimaryClipInternal(getClipboard(id), clip); 185ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 186ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 187ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 188ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 189ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 190ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 191ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 192ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 193ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public ClipData getPrimaryClip(String pkg) { 194ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (this) { 195ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), 196ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka pkg) != AppOpsManager.MODE_ALLOWED) { 197ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return null; 198e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 199ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka addActiveOwnerLocked(Binder.getCallingUid(), pkg); 200ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return getClipboard().primaryClip; 201e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 202ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 20390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 204ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 205ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public ClipDescription getPrimaryClipDescription(String callingPackage) { 206ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (this) { 207ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), 208ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka callingPackage) != AppOpsManager.MODE_ALLOWED) { 209ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return null; 210ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 211ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka PerUserClipboard clipboard = getClipboard(); 212ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return clipboard.primaryClip != null ? clipboard.primaryClip.getDescription() : null; 213164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn } 21490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 215ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 216ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 217ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public boolean hasPrimaryClip(String callingPackage) { 218ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (this) { 219ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), 220ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka callingPackage) != AppOpsManager.MODE_ALLOWED) { 221ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return false; 222ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 223ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return getClipboard().primaryClip != null; 224ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 225ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 226ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 227ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 228ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener, 229ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka String callingPackage) { 230ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (this) { 231ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka getClipboard().primaryClipListeners.register(listener, 232ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka new ListenerInfo(Binder.getCallingUid(), callingPackage)); 233ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 234ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 235ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 236ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 237ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public void removePrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) { 238ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (this) { 239ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka getClipboard().primaryClipListeners.unregister(listener); 240ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 241ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 242ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka 243ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka @Override 244ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka public boolean hasClipboardText(String callingPackage) { 245ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka synchronized (this) { 246ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), 247ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka callingPackage) != AppOpsManager.MODE_ALLOWED) { 248ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return false; 249ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 250ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka PerUserClipboard clipboard = getClipboard(); 251ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka if (clipboard.primaryClip != null) { 252ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka CharSequence text = clipboard.primaryClip.getItemAt(0).getText(); 253ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return text != null && text.length() > 0; 254ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 255ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka return false; 256ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 257ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka } 258ad70bc6c310f54d4810e67b49e7881c1f33a1d83Sudheer Shanka }; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 260e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani private PerUserClipboard getClipboard() { 261f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getClipboard(UserHandle.getCallingUserId()); 262e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 263e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 264e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani private PerUserClipboard getClipboard(int userId) { 265e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani synchronized (mClipboards) { 266e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani PerUserClipboard puc = mClipboards.get(userId); 267e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani if (puc == null) { 268e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani puc = new PerUserClipboard(userId); 269e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani mClipboards.put(userId, puc); 270e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 271e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani return puc; 272e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 273e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani } 274e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani 275f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot List<UserInfo> getRelatedProfiles(int userId) { 276f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot final List<UserInfo> related; 277f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot final long origId = Binder.clearCallingIdentity(); 278f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot try { 279f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot related = mUm.getProfiles(userId, true); 280f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot } catch (RemoteException e) { 281f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot Slog.e(TAG, "Remote Exception calling UserManager: " + e); 282f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot return null; 283f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot } finally{ 284f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot Binder.restoreCallingIdentity(origId); 285f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot } 286f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot return related; 287f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot } 288f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot 289f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot void setPrimaryClipInternal(PerUserClipboard clipboard, ClipData clip) { 290f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot clipboard.activePermissionOwners.clear(); 291f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot if (clip == null && clipboard.primaryClip == null) { 292f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot return; 293f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot } 294f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot clipboard.primaryClip = clip; 295f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot final long ident = Binder.clearCallingIdentity(); 296f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot final int n = clipboard.primaryClipListeners.beginBroadcast(); 297f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot try { 298f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot for (int i = 0; i < n; i++) { 299f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot try { 300f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot ListenerInfo li = (ListenerInfo) 301f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot clipboard.primaryClipListeners.getBroadcastCookie(i); 302f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid, 303f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot li.mPackageName) == AppOpsManager.MODE_ALLOWED) { 304f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot clipboard.primaryClipListeners.getBroadcastItem(i) 305f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot .dispatchPrimaryClipChanged(); 306efcc1a23a1f731390ef8506b3536b9562d18ed78Dianne Hackborn } 307f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot } catch (RemoteException e) { 308f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot // The RemoteCallbackList will take care of removing 309f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot // the dead object for us. 3109f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 3119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 312f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot } finally { 313f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot clipboard.primaryClipListeners.finishBroadcast(); 314f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot Binder.restoreCallingIdentity(ident); 3159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 3169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 31790f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 31890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final void checkUriOwnerLocked(Uri uri, int uid) { 31990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn if (!"content".equals(uri.getScheme())) { 32090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn return; 32190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 32290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn long ident = Binder.clearCallingIdentity(); 32390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn try { 32490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn // This will throw SecurityException for us. 325d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot mAm.checkGrantUriPermission(uid, null, ContentProvider.getUriWithoutUserId(uri), 326f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot Intent.FLAG_GRANT_READ_URI_PERMISSION, 327f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(uid))); 32890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } catch (RemoteException e) { 32990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } finally { 33090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn Binder.restoreCallingIdentity(ident); 33190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 33290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 33390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 33490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final void checkItemOwnerLocked(ClipData.Item item, int uid) { 33590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn if (item.getUri() != null) { 33690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn checkUriOwnerLocked(item.getUri(), uid); 33790f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 33890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn Intent intent = item.getIntent(); 33990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn if (intent != null && intent.getData() != null) { 34090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn checkUriOwnerLocked(intent.getData(), uid); 34190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 34290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 34390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 34490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final void checkDataOwnerLocked(ClipData data, int uid) { 34590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn final int N = data.getItemCount(); 34690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn for (int i=0; i<N; i++) { 347327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn checkItemOwnerLocked(data.getItemAt(i), uid); 34890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 34990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 35090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 351f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot private final void grantUriLocked(Uri uri, String pkg, int userId) { 35290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn long ident = Binder.clearCallingIdentity(); 35390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn try { 354f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot int sourceUserId = ContentProvider.getUserIdFromUri(uri, userId); 355f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot uri = ContentProvider.getUriWithoutUserId(uri); 356d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot mAm.grantUriPermissionFromOwner(mPermissionOwner, Process.myUid(), pkg, 357f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, sourceUserId, userId); 35890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } catch (RemoteException e) { 35990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } finally { 36090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn Binder.restoreCallingIdentity(ident); 36190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 36290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 36390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 364f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot private final void grantItemLocked(ClipData.Item item, String pkg, int userId) { 36590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn if (item.getUri() != null) { 366f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot grantUriLocked(item.getUri(), pkg, userId); 36790f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 36890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn Intent intent = item.getIntent(); 36990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn if (intent != null && intent.getData() != null) { 370f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot grantUriLocked(intent.getData(), pkg, userId); 37190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 37290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 37390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 37490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final void addActiveOwnerLocked(int uid, String pkg) { 375ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate final IPackageManager pm = AppGlobals.getPackageManager(); 376ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate final int targetUserHandle = UserHandle.getCallingUserId(); 377ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate final long oldIdentity = Binder.clearCallingIdentity(); 37890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn try { 379ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate PackageInfo pi = pm.getPackageInfo(pkg, 0, targetUserHandle); 380ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate if (pi == null) { 381ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate throw new IllegalArgumentException("Unknown package " + pkg); 382ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate } 383f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn if (!UserHandle.isSameApp(pi.applicationInfo.uid, uid)) { 38490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn throw new SecurityException("Calling uid " + uid 38590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn + " does not own package " + pkg); 38690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 387ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate } catch (RemoteException e) { 388ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate // Can't happen; the package manager is in the same process 389ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate } finally { 390ad9833a77ff4deb5352c67800c2ee62ed6e51356Christopher Tate Binder.restoreCallingIdentity(oldIdentity); 39190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 392e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani PerUserClipboard clipboard = getClipboard(); 393e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani if (clipboard.primaryClip != null && !clipboard.activePermissionOwners.contains(pkg)) { 394e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani final int N = clipboard.primaryClip.getItemCount(); 39590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn for (int i=0; i<N; i++) { 396f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot grantItemLocked(clipboard.primaryClip.getItemAt(i), pkg, UserHandle.getUserId(uid)); 39790f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 398e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani clipboard.activePermissionOwners.add(pkg); 39990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 40090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 40190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 40290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final void revokeUriLocked(Uri uri) { 403f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot int userId = ContentProvider.getUserIdFromUri(uri, 404f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot UserHandle.getUserId(Binder.getCallingUid())); 40590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn long ident = Binder.clearCallingIdentity(); 40690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn try { 407f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot uri = ContentProvider.getUriWithoutUserId(uri); 408f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot mAm.revokeUriPermissionFromOwner(mPermissionOwner, uri, 409d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 410f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot userId); 41190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } catch (RemoteException e) { 41290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } finally { 41390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn Binder.restoreCallingIdentity(ident); 41490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 41590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 41690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 41790f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn private final void revokeItemLocked(ClipData.Item item) { 41890f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn if (item.getUri() != null) { 41990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn revokeUriLocked(item.getUri()); 42090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 42190f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn Intent intent = item.getIntent(); 42290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn if (intent != null && intent.getData() != null) { 42390f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn revokeUriLocked(intent.getData()); 42490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 42590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 42690f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn 427f1939901d2ed0480069f0b23be64f122fce93995Nicolas Prevot private final void revokeUris(PerUserClipboard clipboard) { 428e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani if (clipboard.primaryClip == null) { 42990f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn return; 43090f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 431e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani final int N = clipboard.primaryClip.getItemCount(); 43290f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn for (int i=0; i<N; i++) { 433e9e26cc727a1490db5eb0e572a40913f624529feAmith Yamasani revokeItemLocked(clipboard.primaryClip.getItemAt(i)); 43490f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 43590f4aafa336d9f2f07281ead3c846d323a710015Dianne Hackborn } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 437