Merge "Add attribution tag to clipboard." into tm-qpr-dev

This commit is contained in:
Achim Thesmann
2022-07-07 17:16:35 +00:00
committed by Android (Google) Code Review
3 changed files with 168 additions and 66 deletions

View File

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

View File

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

View File

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