Loading core/java/android/app/AppOpsManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -93,8 +93,10 @@ public class AppOpsManager { public static final int OP_CAMERA = 26; public static final int OP_RECORD_AUDIO = 27; public static final int OP_PLAY_AUDIO = 28; public static final int OP_READ_CLIPBOARD = 29; public static final int OP_WRITE_CLIPBOARD = 30; /** @hide */ public static final int _NUM_OP = 29; public static final int _NUM_OP = 31; /** * This maps each operation to the operation that serves as the Loading Loading @@ -134,6 +136,8 @@ public class AppOpsManager { OP_CAMERA, OP_RECORD_AUDIO, OP_PLAY_AUDIO, OP_READ_CLIPBOARD, OP_WRITE_CLIPBOARD, }; /** Loading Loading @@ -170,6 +174,8 @@ public class AppOpsManager { "CAMERA", "RECORD_AUDIO", "PLAY_AUDIO", "READ_CLIPBOARD", "WRITE_CLIPBOARD", }; /** Loading Loading @@ -206,6 +212,8 @@ public class AppOpsManager { android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO, null, // no permission for playing audio null, // no permission for reading clipboard null, // no permission for writing clipboard }; /** Loading core/java/android/content/ClipboardManager.java +6 −6 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public void setPrimaryClip(ClipData clip) { try { getService().setPrimaryClip(clip); getService().setPrimaryClip(clip, mContext.getBasePackageName()); } catch (RemoteException e) { } } Loading @@ -128,7 +128,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public ClipData getPrimaryClip() { try { return getService().getPrimaryClip(mContext.getPackageName()); return getService().getPrimaryClip(mContext.getBasePackageName()); } catch (RemoteException e) { return null; } Loading @@ -140,7 +140,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public ClipDescription getPrimaryClipDescription() { try { return getService().getPrimaryClipDescription(); return getService().getPrimaryClipDescription(mContext.getBasePackageName()); } catch (RemoteException e) { return null; } Loading @@ -151,7 +151,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public boolean hasPrimaryClip() { try { return getService().hasPrimaryClip(); return getService().hasPrimaryClip(mContext.getBasePackageName()); } catch (RemoteException e) { return false; } Loading @@ -162,7 +162,7 @@ public class ClipboardManager extends android.text.ClipboardManager { if (mPrimaryClipChangedListeners.size() == 0) { try { getService().addPrimaryClipChangedListener( mPrimaryClipChangedServiceListener); mPrimaryClipChangedServiceListener, mContext.getBasePackageName()); } catch (RemoteException e) { } } Loading Loading @@ -209,7 +209,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public boolean hasText() { try { return getService().hasClipboardText(); return getService().hasClipboardText(mContext.getBasePackageName()); } catch (RemoteException e) { return false; } Loading core/java/android/content/IClipboard.aidl +6 −5 Original line number Diff line number Diff line Loading @@ -26,15 +26,16 @@ import android.content.IOnPrimaryClipChangedListener; * {@hide} */ interface IClipboard { void setPrimaryClip(in ClipData clip); void setPrimaryClip(in ClipData clip, String callingPackage); ClipData getPrimaryClip(String pkg); ClipDescription getPrimaryClipDescription(); boolean hasPrimaryClip(); void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener); ClipDescription getPrimaryClipDescription(String callingPackage); boolean hasPrimaryClip(String callingPackage); void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener, String callingPackage); void removePrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener); /** * Returns true if the clipboard contains text; false otherwise. */ boolean hasClipboardText(); boolean hasClipboardText(String callingPackage); } services/java/com/android/server/ClipboardService.java +47 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.IActivityManager; import android.content.BroadcastReceiver; import android.content.ClipData; Loading Loading @@ -55,8 +56,18 @@ public class ClipboardService extends IClipboard.Stub { private final Context mContext; private final IActivityManager mAm; private final PackageManager mPm; private final AppOpsManager mAppOps; private final IBinder mPermissionOwner; private class ListenerInfo { final int mUid; final String mPackageName; ListenerInfo(int uid, String packageName) { mUid = uid; mPackageName = packageName; } } private class PerUserClipboard { final int userId; Loading @@ -82,6 +93,7 @@ public class ClipboardService extends IClipboard.Stub { mContext = context; mAm = ActivityManagerNative.getDefault(); mPm = context.getPackageManager(); mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); IBinder permOwner = null; try { permOwner = mAm.newUriPermissionOwner("clipboard"); Loading Loading @@ -137,11 +149,15 @@ public class ClipboardService extends IClipboard.Stub { } } public void setPrimaryClip(ClipData clip) { public void setPrimaryClip(ClipData clip, String callingPackage) { synchronized (this) { if (clip != null && clip.getItemCount() <= 0) { throw new IllegalArgumentException("No items"); } if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return; } checkDataOwnerLocked(clip, Binder.getCallingUid()); clearActiveOwnersLocked(); PerUserClipboard clipboard = getClipboard(); Loading @@ -149,7 +165,13 @@ public class ClipboardService extends IClipboard.Stub { final int n = clipboard.primaryClipListeners.beginBroadcast(); for (int i = 0; i < n; i++) { try { clipboard.primaryClipListeners.getBroadcastItem(i).dispatchPrimaryClipChanged(); ListenerInfo li = (ListenerInfo) clipboard.primaryClipListeners.getBroadcastCookie(i); if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid, li.mPackageName) == AppOpsManager.MODE_ALLOWED) { clipboard.primaryClipListeners.getBroadcastItem(i) .dispatchPrimaryClipChanged(); } } catch (RemoteException e) { // The RemoteCallbackList will take care of removing Loading @@ -162,27 +184,41 @@ public class ClipboardService extends IClipboard.Stub { public ClipData getPrimaryClip(String pkg) { synchronized (this) { if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), pkg) != AppOpsManager.MODE_ALLOWED) { return null; } addActiveOwnerLocked(Binder.getCallingUid(), pkg); return getClipboard().primaryClip; } } public ClipDescription getPrimaryClipDescription() { public ClipDescription getPrimaryClipDescription(String callingPackage) { synchronized (this) { if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return null; } PerUserClipboard clipboard = getClipboard(); return clipboard.primaryClip != null ? clipboard.primaryClip.getDescription() : null; } } public boolean hasPrimaryClip() { public boolean hasPrimaryClip(String callingPackage) { synchronized (this) { if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return false; } return getClipboard().primaryClip != null; } } public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) { public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener, String callingPackage) { synchronized (this) { getClipboard().primaryClipListeners.register(listener); getClipboard().primaryClipListeners.register(listener, new ListenerInfo(Binder.getCallingUid(), callingPackage)); } } Loading @@ -192,8 +228,12 @@ public class ClipboardService extends IClipboard.Stub { } } public boolean hasClipboardText() { public boolean hasClipboardText(String callingPackage) { synchronized (this) { if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return false; } PerUserClipboard clipboard = getClipboard(); if (clipboard.primaryClip != null) { CharSequence text = clipboard.primaryClip.getItemAt(0).getText(); Loading Loading
core/java/android/app/AppOpsManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -93,8 +93,10 @@ public class AppOpsManager { public static final int OP_CAMERA = 26; public static final int OP_RECORD_AUDIO = 27; public static final int OP_PLAY_AUDIO = 28; public static final int OP_READ_CLIPBOARD = 29; public static final int OP_WRITE_CLIPBOARD = 30; /** @hide */ public static final int _NUM_OP = 29; public static final int _NUM_OP = 31; /** * This maps each operation to the operation that serves as the Loading Loading @@ -134,6 +136,8 @@ public class AppOpsManager { OP_CAMERA, OP_RECORD_AUDIO, OP_PLAY_AUDIO, OP_READ_CLIPBOARD, OP_WRITE_CLIPBOARD, }; /** Loading Loading @@ -170,6 +174,8 @@ public class AppOpsManager { "CAMERA", "RECORD_AUDIO", "PLAY_AUDIO", "READ_CLIPBOARD", "WRITE_CLIPBOARD", }; /** Loading Loading @@ -206,6 +212,8 @@ public class AppOpsManager { android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO, null, // no permission for playing audio null, // no permission for reading clipboard null, // no permission for writing clipboard }; /** Loading
core/java/android/content/ClipboardManager.java +6 −6 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public void setPrimaryClip(ClipData clip) { try { getService().setPrimaryClip(clip); getService().setPrimaryClip(clip, mContext.getBasePackageName()); } catch (RemoteException e) { } } Loading @@ -128,7 +128,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public ClipData getPrimaryClip() { try { return getService().getPrimaryClip(mContext.getPackageName()); return getService().getPrimaryClip(mContext.getBasePackageName()); } catch (RemoteException e) { return null; } Loading @@ -140,7 +140,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public ClipDescription getPrimaryClipDescription() { try { return getService().getPrimaryClipDescription(); return getService().getPrimaryClipDescription(mContext.getBasePackageName()); } catch (RemoteException e) { return null; } Loading @@ -151,7 +151,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public boolean hasPrimaryClip() { try { return getService().hasPrimaryClip(); return getService().hasPrimaryClip(mContext.getBasePackageName()); } catch (RemoteException e) { return false; } Loading @@ -162,7 +162,7 @@ public class ClipboardManager extends android.text.ClipboardManager { if (mPrimaryClipChangedListeners.size() == 0) { try { getService().addPrimaryClipChangedListener( mPrimaryClipChangedServiceListener); mPrimaryClipChangedServiceListener, mContext.getBasePackageName()); } catch (RemoteException e) { } } Loading Loading @@ -209,7 +209,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public boolean hasText() { try { return getService().hasClipboardText(); return getService().hasClipboardText(mContext.getBasePackageName()); } catch (RemoteException e) { return false; } Loading
core/java/android/content/IClipboard.aidl +6 −5 Original line number Diff line number Diff line Loading @@ -26,15 +26,16 @@ import android.content.IOnPrimaryClipChangedListener; * {@hide} */ interface IClipboard { void setPrimaryClip(in ClipData clip); void setPrimaryClip(in ClipData clip, String callingPackage); ClipData getPrimaryClip(String pkg); ClipDescription getPrimaryClipDescription(); boolean hasPrimaryClip(); void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener); ClipDescription getPrimaryClipDescription(String callingPackage); boolean hasPrimaryClip(String callingPackage); void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener, String callingPackage); void removePrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener); /** * Returns true if the clipboard contains text; false otherwise. */ boolean hasClipboardText(); boolean hasClipboardText(String callingPackage); }
services/java/com/android/server/ClipboardService.java +47 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.IActivityManager; import android.content.BroadcastReceiver; import android.content.ClipData; Loading Loading @@ -55,8 +56,18 @@ public class ClipboardService extends IClipboard.Stub { private final Context mContext; private final IActivityManager mAm; private final PackageManager mPm; private final AppOpsManager mAppOps; private final IBinder mPermissionOwner; private class ListenerInfo { final int mUid; final String mPackageName; ListenerInfo(int uid, String packageName) { mUid = uid; mPackageName = packageName; } } private class PerUserClipboard { final int userId; Loading @@ -82,6 +93,7 @@ public class ClipboardService extends IClipboard.Stub { mContext = context; mAm = ActivityManagerNative.getDefault(); mPm = context.getPackageManager(); mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); IBinder permOwner = null; try { permOwner = mAm.newUriPermissionOwner("clipboard"); Loading Loading @@ -137,11 +149,15 @@ public class ClipboardService extends IClipboard.Stub { } } public void setPrimaryClip(ClipData clip) { public void setPrimaryClip(ClipData clip, String callingPackage) { synchronized (this) { if (clip != null && clip.getItemCount() <= 0) { throw new IllegalArgumentException("No items"); } if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return; } checkDataOwnerLocked(clip, Binder.getCallingUid()); clearActiveOwnersLocked(); PerUserClipboard clipboard = getClipboard(); Loading @@ -149,7 +165,13 @@ public class ClipboardService extends IClipboard.Stub { final int n = clipboard.primaryClipListeners.beginBroadcast(); for (int i = 0; i < n; i++) { try { clipboard.primaryClipListeners.getBroadcastItem(i).dispatchPrimaryClipChanged(); ListenerInfo li = (ListenerInfo) clipboard.primaryClipListeners.getBroadcastCookie(i); if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid, li.mPackageName) == AppOpsManager.MODE_ALLOWED) { clipboard.primaryClipListeners.getBroadcastItem(i) .dispatchPrimaryClipChanged(); } } catch (RemoteException e) { // The RemoteCallbackList will take care of removing Loading @@ -162,27 +184,41 @@ public class ClipboardService extends IClipboard.Stub { public ClipData getPrimaryClip(String pkg) { synchronized (this) { if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), pkg) != AppOpsManager.MODE_ALLOWED) { return null; } addActiveOwnerLocked(Binder.getCallingUid(), pkg); return getClipboard().primaryClip; } } public ClipDescription getPrimaryClipDescription() { public ClipDescription getPrimaryClipDescription(String callingPackage) { synchronized (this) { if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return null; } PerUserClipboard clipboard = getClipboard(); return clipboard.primaryClip != null ? clipboard.primaryClip.getDescription() : null; } } public boolean hasPrimaryClip() { public boolean hasPrimaryClip(String callingPackage) { synchronized (this) { if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return false; } return getClipboard().primaryClip != null; } } public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) { public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener, String callingPackage) { synchronized (this) { getClipboard().primaryClipListeners.register(listener); getClipboard().primaryClipListeners.register(listener, new ListenerInfo(Binder.getCallingUid(), callingPackage)); } } Loading @@ -192,8 +228,12 @@ public class ClipboardService extends IClipboard.Stub { } } public boolean hasClipboardText() { public boolean hasClipboardText(String callingPackage) { synchronized (this) { if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return false; } PerUserClipboard clipboard = getClipboard(); if (clipboard.primaryClip != null) { CharSequence text = clipboard.primaryClip.getItemAt(0).getText(); Loading