Add attribution tag to clipboard.
Bug: 235542330 Test: ClipboardManagerTest ClipboardAutoClearTest ClipboardManagerTest ClipboardManagerListenerTest ClipboardAccessTest ClipboardAccessTest Test: manually tested copy-paste Change-Id: I122a48a299f890ac565afb1042615edfa263b1c7
This commit is contained in:
@@ -129,7 +129,11 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
try {
|
||||
Objects.requireNonNull(clip);
|
||||
clip.prepareToLeaveProcess(true);
|
||||
mService.setPrimaryClip(clip, mContext.getOpPackageName(), mContext.getUserId());
|
||||
mService.setPrimaryClip(
|
||||
clip,
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -154,7 +158,11 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
Objects.requireNonNull(sourcePackage);
|
||||
clip.prepareToLeaveProcess(true);
|
||||
mService.setPrimaryClipAsPackage(
|
||||
clip, mContext.getOpPackageName(), mContext.getUserId(), sourcePackage);
|
||||
clip,
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId(),
|
||||
sourcePackage);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -167,7 +175,10 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
*/
|
||||
public void clearPrimaryClip() {
|
||||
try {
|
||||
mService.clearPrimaryClip(mContext.getOpPackageName(), mContext.getUserId());
|
||||
mService.clearPrimaryClip(
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -183,24 +194,29 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
*/
|
||||
public @Nullable ClipData getPrimaryClip() {
|
||||
try {
|
||||
return mService.getPrimaryClip(mContext.getOpPackageName(), mContext.getUserId());
|
||||
return mService.getPrimaryClip(
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a description of the current primary clip on the clipboard
|
||||
* but not a copy of its data.
|
||||
* Returns a description of the current primary clip on the clipboard but not a copy of its
|
||||
* data.
|
||||
*
|
||||
* <em>If the application is not the default IME or does not have input focus this return
|
||||
* <p><em>If the application is not the default IME or does not have input focus this return
|
||||
* {@code null}.</em>
|
||||
*
|
||||
* @see #setPrimaryClip(ClipData)
|
||||
*/
|
||||
public @Nullable ClipDescription getPrimaryClipDescription() {
|
||||
try {
|
||||
return mService.getPrimaryClipDescription(mContext.getOpPackageName(),
|
||||
return mService.getPrimaryClipDescription(
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
@@ -215,7 +231,10 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
*/
|
||||
public boolean hasPrimaryClip() {
|
||||
try {
|
||||
return mService.hasPrimaryClip(mContext.getOpPackageName(), mContext.getUserId());
|
||||
return mService.hasPrimaryClip(
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -226,7 +245,9 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
if (mPrimaryClipChangedListeners.isEmpty()) {
|
||||
try {
|
||||
mService.addPrimaryClipChangedListener(
|
||||
mPrimaryClipChangedServiceListener, mContext.getOpPackageName(),
|
||||
mPrimaryClipChangedServiceListener,
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
@@ -242,7 +263,9 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
if (mPrimaryClipChangedListeners.isEmpty()) {
|
||||
try {
|
||||
mService.removePrimaryClipChangedListener(
|
||||
mPrimaryClipChangedServiceListener, mContext.getOpPackageName(),
|
||||
mPrimaryClipChangedServiceListener,
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
@@ -280,7 +303,10 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
@Deprecated
|
||||
public boolean hasText() {
|
||||
try {
|
||||
return mService.hasClipboardText(mContext.getOpPackageName(), mContext.getUserId());
|
||||
return mService.hasClipboardText(
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -297,7 +323,10 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
@RequiresPermission(Manifest.permission.SET_CLIP_SOURCE)
|
||||
public String getPrimaryClipSource() {
|
||||
try {
|
||||
return mService.getPrimaryClipSource(mContext.getOpPackageName(), mContext.getUserId());
|
||||
return mService.getPrimaryClipSource(
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -26,22 +26,22 @@ import android.content.IOnPrimaryClipChangedListener;
|
||||
* {@hide}
|
||||
*/
|
||||
interface IClipboard {
|
||||
void setPrimaryClip(in ClipData clip, String callingPackage, int userId);
|
||||
void setPrimaryClipAsPackage(in ClipData clip, String callingPackage, int userId,
|
||||
void setPrimaryClip(in ClipData clip, String callingPackage, String attributionTag, int userId);
|
||||
void setPrimaryClipAsPackage(in ClipData clip, String callingPackage, String attributionTag, int userId,
|
||||
String sourcePackage);
|
||||
void clearPrimaryClip(String callingPackage, int userId);
|
||||
ClipData getPrimaryClip(String pkg, int userId);
|
||||
ClipDescription getPrimaryClipDescription(String callingPackage, int userId);
|
||||
boolean hasPrimaryClip(String callingPackage, int userId);
|
||||
void clearPrimaryClip(String callingPackage, String attributionTag, int userId);
|
||||
ClipData getPrimaryClip(String pkg, String attributionTag, int userId);
|
||||
ClipDescription getPrimaryClipDescription(String callingPackage, String attributionTag, int userId);
|
||||
boolean hasPrimaryClip(String callingPackage, String attributionTag, int userId);
|
||||
void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener,
|
||||
String callingPackage, int userId);
|
||||
String callingPackage, String attributionTag, int userId);
|
||||
void removePrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener,
|
||||
String callingPackage, int userId);
|
||||
String callingPackage, String attributionTag, int userId);
|
||||
|
||||
/**
|
||||
* Returns true if the clipboard contains text; false otherwise.
|
||||
*/
|
||||
boolean hasClipboardText(String callingPackage, int userId);
|
||||
boolean hasClipboardText(String callingPackage, String attributionTag, int userId);
|
||||
|
||||
String getPrimaryClipSource(String callingPackage, int userId);
|
||||
String getPrimaryClipSource(String callingPackage, String attributionTag, int userId);
|
||||
}
|
||||
|
||||
@@ -215,9 +215,12 @@ public class ClipboardService extends SystemService {
|
||||
private class ListenerInfo {
|
||||
final int mUid;
|
||||
final String mPackageName;
|
||||
ListenerInfo(int uid, String packageName) {
|
||||
final String mAttributionTag;
|
||||
|
||||
ListenerInfo(int uid, String packageName, String attributionTag) {
|
||||
mUid = uid;
|
||||
mPackageName = packageName;
|
||||
mAttributionTag = attributionTag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,27 +358,43 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrimaryClip(ClipData clip, String callingPackage, @UserIdInt int userId) {
|
||||
checkAndSetPrimaryClip(clip, callingPackage, userId, callingPackage);
|
||||
public void setPrimaryClip(
|
||||
ClipData clip,
|
||||
String callingPackage,
|
||||
String attributionTag,
|
||||
@UserIdInt int userId) {
|
||||
checkAndSetPrimaryClip(clip, callingPackage, attributionTag, userId, callingPackage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrimaryClipAsPackage(
|
||||
ClipData clip, String callingPackage, @UserIdInt int userId, String sourcePackage) {
|
||||
ClipData clip,
|
||||
String callingPackage,
|
||||
String attributionTag,
|
||||
@UserIdInt int userId,
|
||||
String sourcePackage) {
|
||||
getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
|
||||
"Requires SET_CLIP_SOURCE permission");
|
||||
checkAndSetPrimaryClip(clip, callingPackage, userId, sourcePackage);
|
||||
checkAndSetPrimaryClip(clip, callingPackage, attributionTag, userId, sourcePackage);
|
||||
}
|
||||
|
||||
private void checkAndSetPrimaryClip(
|
||||
ClipData clip, String callingPackage, @UserIdInt int userId, String sourcePackage) {
|
||||
ClipData clip,
|
||||
String callingPackage,
|
||||
String attributionTag,
|
||||
@UserIdInt int userId,
|
||||
String sourcePackage) {
|
||||
if (clip == null || clip.getItemCount() <= 0) {
|
||||
throw new IllegalArgumentException("No items");
|
||||
}
|
||||
final int intendingUid = getIntendingUid(callingPackage, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage,
|
||||
intendingUid, intendingUserId)) {
|
||||
if (!clipboardAccessAllowed(
|
||||
AppOpsManager.OP_WRITE_CLIPBOARD,
|
||||
callingPackage,
|
||||
attributionTag,
|
||||
intendingUid,
|
||||
intendingUserId)) {
|
||||
return;
|
||||
}
|
||||
checkDataOwner(clip, intendingUid);
|
||||
@@ -392,8 +411,13 @@ public class ClipboardService extends SystemService {
|
||||
PROPERTY_AUTO_CLEAR_ENABLED, true)) {
|
||||
mClipboardClearHandler.removeEqualMessages(ClipboardClearHandler.MSG_CLEAR,
|
||||
userId);
|
||||
Message clearMessage = Message.obtain(mClipboardClearHandler,
|
||||
ClipboardClearHandler.MSG_CLEAR, userId, intendingUid, userId);
|
||||
Message clearMessage =
|
||||
Message.obtain(
|
||||
mClipboardClearHandler,
|
||||
ClipboardClearHandler.MSG_CLEAR,
|
||||
userId,
|
||||
intendingUid,
|
||||
userId);
|
||||
mClipboardClearHandler.sendMessageDelayed(clearMessage,
|
||||
getTimeoutForAutoClear());
|
||||
}
|
||||
@@ -409,11 +433,16 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPrimaryClip(String callingPackage, @UserIdInt int userId) {
|
||||
public void clearPrimaryClip(
|
||||
String callingPackage, String attributionTag, @UserIdInt int userId) {
|
||||
final int intendingUid = getIntendingUid(callingPackage, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage,
|
||||
intendingUid, intendingUserId)) {
|
||||
if (!clipboardAccessAllowed(
|
||||
AppOpsManager.OP_WRITE_CLIPBOARD,
|
||||
callingPackage,
|
||||
attributionTag,
|
||||
intendingUid,
|
||||
intendingUserId)) {
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
@@ -424,11 +453,15 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipData getPrimaryClip(String pkg, @UserIdInt int userId) {
|
||||
public ClipData getPrimaryClip(String pkg, String attributionTag, @UserIdInt int userId) {
|
||||
final int intendingUid = getIntendingUid(pkg, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, pkg,
|
||||
intendingUid, intendingUserId)
|
||||
if (!clipboardAccessAllowed(
|
||||
AppOpsManager.OP_READ_CLIPBOARD,
|
||||
pkg,
|
||||
attributionTag,
|
||||
intendingUid,
|
||||
intendingUserId)
|
||||
|| isDeviceLocked(intendingUserId)) {
|
||||
return null;
|
||||
}
|
||||
@@ -453,12 +486,17 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipDescription getPrimaryClipDescription(String callingPackage,
|
||||
@UserIdInt int userId) {
|
||||
public ClipDescription getPrimaryClipDescription(
|
||||
String callingPackage, String attributionTag, @UserIdInt int userId) {
|
||||
final int intendingUid = getIntendingUid(callingPackage, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
|
||||
intendingUid, intendingUserId, false)
|
||||
if (!clipboardAccessAllowed(
|
||||
AppOpsManager.OP_READ_CLIPBOARD,
|
||||
callingPackage,
|
||||
attributionTag,
|
||||
intendingUid,
|
||||
intendingUserId,
|
||||
false)
|
||||
|| isDeviceLocked(intendingUserId)) {
|
||||
return null;
|
||||
}
|
||||
@@ -470,11 +508,17 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrimaryClip(String callingPackage, @UserIdInt int userId) {
|
||||
public boolean hasPrimaryClip(
|
||||
String callingPackage, String attributionTag, @UserIdInt int userId) {
|
||||
final int intendingUid = getIntendingUid(callingPackage, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
|
||||
intendingUid, intendingUserId, false)
|
||||
if (!clipboardAccessAllowed(
|
||||
AppOpsManager.OP_READ_CLIPBOARD,
|
||||
callingPackage,
|
||||
attributionTag,
|
||||
intendingUid,
|
||||
intendingUserId,
|
||||
false)
|
||||
|| isDeviceLocked(intendingUserId)) {
|
||||
return false;
|
||||
}
|
||||
@@ -484,19 +528,28 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener,
|
||||
String callingPackage, @UserIdInt int userId) {
|
||||
public void addPrimaryClipChangedListener(
|
||||
IOnPrimaryClipChangedListener listener,
|
||||
String callingPackage,
|
||||
String attributionTag,
|
||||
@UserIdInt int userId) {
|
||||
final int intendingUid = getIntendingUid(callingPackage, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
synchronized (mLock) {
|
||||
getClipboardLocked(intendingUserId).primaryClipListeners.register(listener,
|
||||
new ListenerInfo(intendingUid, callingPackage));
|
||||
getClipboardLocked(intendingUserId)
|
||||
.primaryClipListeners
|
||||
.register(
|
||||
listener,
|
||||
new ListenerInfo(intendingUid, callingPackage, attributionTag));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePrimaryClipChangedListener(IOnPrimaryClipChangedListener listener,
|
||||
String callingPackage, @UserIdInt int userId) {
|
||||
public void removePrimaryClipChangedListener(
|
||||
IOnPrimaryClipChangedListener listener,
|
||||
String callingPackage,
|
||||
String attributionTag,
|
||||
@UserIdInt int userId) {
|
||||
final int intendingUserId = getIntendingUserId(callingPackage, userId);
|
||||
synchronized (mLock) {
|
||||
getClipboardLocked(intendingUserId).primaryClipListeners.unregister(listener);
|
||||
@@ -504,11 +557,16 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasClipboardText(String callingPackage, int userId) {
|
||||
public boolean hasClipboardText(String callingPackage, String attributionTag, int userId) {
|
||||
final int intendingUid = getIntendingUid(callingPackage, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
|
||||
intendingUid, intendingUserId, false)
|
||||
if (!clipboardAccessAllowed(
|
||||
AppOpsManager.OP_READ_CLIPBOARD,
|
||||
callingPackage,
|
||||
attributionTag,
|
||||
intendingUid,
|
||||
intendingUserId,
|
||||
false)
|
||||
|| isDeviceLocked(intendingUserId)) {
|
||||
return false;
|
||||
}
|
||||
@@ -523,13 +581,19 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryClipSource(String callingPackage, int userId) {
|
||||
public String getPrimaryClipSource(
|
||||
String callingPackage, String attributionTag, int userId) {
|
||||
getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
|
||||
"Requires SET_CLIP_SOURCE permission");
|
||||
final int intendingUid = getIntendingUid(callingPackage, userId);
|
||||
final int intendingUserId = UserHandle.getUserId(intendingUid);
|
||||
if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
|
||||
intendingUid, intendingUserId, false)
|
||||
if (!clipboardAccessAllowed(
|
||||
AppOpsManager.OP_READ_CLIPBOARD,
|
||||
callingPackage,
|
||||
attributionTag,
|
||||
intendingUid,
|
||||
intendingUserId,
|
||||
false)
|
||||
|| isDeviceLocked(intendingUserId)) {
|
||||
return null;
|
||||
}
|
||||
@@ -718,8 +782,12 @@ public class ClipboardService extends SystemService {
|
||||
ListenerInfo li = (ListenerInfo)
|
||||
clipboard.primaryClipListeners.getBroadcastCookie(i);
|
||||
|
||||
if (clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, li.mPackageName,
|
||||
li.mUid, UserHandle.getUserId(li.mUid))) {
|
||||
if (clipboardAccessAllowed(
|
||||
AppOpsManager.OP_READ_CLIPBOARD,
|
||||
li.mPackageName,
|
||||
li.mAttributionTag,
|
||||
li.mUid,
|
||||
UserHandle.getUserId(li.mUid))) {
|
||||
clipboard.primaryClipListeners.getBroadcastItem(i)
|
||||
.dispatchPrimaryClipChanged();
|
||||
}
|
||||
@@ -965,13 +1033,18 @@ public class ClipboardService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
|
||||
@UserIdInt int userId) {
|
||||
return clipboardAccessAllowed(op, callingPackage, uid, userId, true);
|
||||
private boolean clipboardAccessAllowed(
|
||||
int op, String callingPackage, String attributionTag, int uid, @UserIdInt int userId) {
|
||||
return clipboardAccessAllowed(op, callingPackage, attributionTag, uid, userId, true);
|
||||
}
|
||||
|
||||
private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
|
||||
@UserIdInt int userId, boolean shouldNoteOp) {
|
||||
private boolean clipboardAccessAllowed(
|
||||
int op,
|
||||
String callingPackage,
|
||||
String attributionTag,
|
||||
int uid,
|
||||
@UserIdInt int userId,
|
||||
boolean shouldNoteOp) {
|
||||
|
||||
boolean allowed;
|
||||
|
||||
@@ -1040,7 +1113,7 @@ public class ClipboardService extends SystemService {
|
||||
// Finally, check the app op.
|
||||
int appOpsResult;
|
||||
if (shouldNoteOp) {
|
||||
appOpsResult = mAppOps.noteOp(op, uid, callingPackage);
|
||||
appOpsResult = mAppOps.noteOp(op, uid, callingPackage, attributionTag, null);
|
||||
} else {
|
||||
appOpsResult = mAppOps.checkOp(op, uid, callingPackage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user