Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efcc1a23 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

App ops: adding operations for reading/writing clipboard.

Change-Id: Ic4cade153618fe86954754a3b3edde64a52a0a9c
parent f4b36ad1
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -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
@@ -134,6 +136,8 @@ public class AppOpsManager {
            OP_CAMERA,
            OP_RECORD_AUDIO,
            OP_PLAY_AUDIO,
            OP_READ_CLIPBOARD,
            OP_WRITE_CLIPBOARD,
    };

    /**
@@ -170,6 +174,8 @@ public class AppOpsManager {
            "CAMERA",
            "RECORD_AUDIO",
            "PLAY_AUDIO",
            "READ_CLIPBOARD",
            "WRITE_CLIPBOARD",
    };

    /**
@@ -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
    };

    /**
+6 −6
Original line number Diff line number Diff line
@@ -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) {
        }
    }
@@ -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;
        }
@@ -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;
        }
@@ -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;
        }
@@ -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) {
                }
            }
@@ -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;
        }
+6 −5
Original line number Diff line number Diff line
@@ -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);
}
+47 −7
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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");
@@ -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();
@@ -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
@@ -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));
        }
    }

@@ -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();