Add system API to attribute source of clip data.
This adds a system API to allow the source package to be included when clip data is set on CLipboardManager. This is needed to ensure that the clipboard access notifications can be properly attributed. For example, when a copy is performed through the share sheet, the data should be attributed to the app that opened the share sheet, not Android System. Bug: 180577866 Test: new tests added to ClipboardManagerTest in CTS Change-Id: Ic0ef2ea218e1dcb738b401f61cd20cd5bba6baec
This commit is contained in:
@@ -16,9 +16,13 @@
|
||||
|
||||
package android.content;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.annotation.TestApi;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
@@ -108,6 +112,31 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current primary clip on the clipboard, attributed to the specified {@code
|
||||
* sourcePackage}. The primary clip is the clip that is involved in normal cut and paste
|
||||
* operations.
|
||||
*
|
||||
* @param clip The clipped data item to set.
|
||||
* @param sourcePackage The package name of the app that is the source of the clip data.
|
||||
* @throws IllegalArgumentException if the clip is null or contains no items.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.SET_CLIP_SOURCE)
|
||||
public void setPrimaryClipAsPackage(@NonNull ClipData clip, @NonNull String sourcePackage) {
|
||||
try {
|
||||
Objects.requireNonNull(clip);
|
||||
Objects.requireNonNull(sourcePackage);
|
||||
clip.prepareToLeaveProcess(true);
|
||||
mService.setPrimaryClipAsPackage(
|
||||
clip, mContext.getOpPackageName(), mContext.getUserId(), sourcePackage);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any current primary clip on the clipboard.
|
||||
*
|
||||
@@ -234,6 +263,23 @@ public class ClipboardManager extends android.text.ClipboardManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the package name of the source of the current primary clip, or null if there is no
|
||||
* primary clip or if a source is not available.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@Nullable
|
||||
@RequiresPermission(Manifest.permission.SET_CLIP_SOURCE)
|
||||
public String getPrimaryClipSource() {
|
||||
try {
|
||||
return mService.getPrimaryClipSource(mContext.getOpPackageName(), mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
void reportPrimaryClipChanged() {
|
||||
Object[] listeners;
|
||||
|
||||
@@ -27,6 +27,8 @@ import android.content.IOnPrimaryClipChangedListener;
|
||||
*/
|
||||
interface IClipboard {
|
||||
void setPrimaryClip(in ClipData clip, String callingPackage, int userId);
|
||||
void setPrimaryClipAsPackage(in ClipData clip, String callingPackage, int userId,
|
||||
String sourcePackage);
|
||||
void clearPrimaryClip(String callingPackage, int userId);
|
||||
ClipData getPrimaryClip(String pkg, int userId);
|
||||
ClipDescription getPrimaryClipDescription(String callingPackage, int userId);
|
||||
@@ -40,4 +42,6 @@ interface IClipboard {
|
||||
* Returns true if the clipboard contains text; false otherwise.
|
||||
*/
|
||||
boolean hasClipboardText(String callingPackage, int userId);
|
||||
|
||||
String getPrimaryClipSource(String callingPackage, int userId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user