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

Commit 01010e4e authored by Oli Lan's avatar Oli Lan Committed by Automerger Merge Worker
Browse files

Add system API to attribute source of clip data. am: 54c65485

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13711625

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ia00495cc03d58ccec1a3d7993df2e879af8a7da6
parents 9c7ca1d9 54c65485
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2120,6 +2120,10 @@ package android.content {
    method @NonNull public final android.os.UserHandle getSendingUser();
  }
  public class ClipboardManager extends android.text.ClipboardManager {
    method @RequiresPermission(android.Manifest.permission.SET_CLIP_SOURCE) public void setPrimaryClipAsPackage(@NonNull android.content.ClipData, @NonNull String);
  }
  public abstract class ContentProvider implements android.content.ComponentCallbacks2 {
    method public int checkUriPermission(@NonNull android.net.Uri, int, int);
  }
+4 −0
Original line number Diff line number Diff line
@@ -658,6 +658,10 @@ package android.content {
    field @Nullable public android.util.ArraySet<android.content.ComponentName> whitelistedActivitiesForAugmentedAutofill;
  }

  public class ClipboardManager extends android.text.ClipboardManager {
    method @Nullable @RequiresPermission(android.Manifest.permission.SET_CLIP_SOURCE) public String getPrimaryClipSource();
  }

  public final class ContentCaptureOptions implements android.os.Parcelable {
    ctor public ContentCaptureOptions(int);
    ctor public ContentCaptureOptions(int, int, int, int, int, @Nullable android.util.ArraySet<android.content.ComponentName>);
+46 −0
Original line number Diff line number Diff line
@@ -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;
+4 −0
Original line number Diff line number Diff line
@@ -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);
}
+48 −11
Original line number Diff line number Diff line
@@ -379,6 +379,24 @@ public class ClipboardService extends SystemService {
        @Override
        public void setPrimaryClip(ClipData clip, String callingPackage, @UserIdInt int userId) {
            synchronized (this) {
                checkAndSetPrimaryClipLocked(clip, callingPackage, userId, callingPackage);
            }
        }

        @Override
        public void setPrimaryClipAsPackage(
                ClipData clip, String callingPackage, @UserIdInt int userId, String sourcePackage) {
            getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
                    "Requires SET_CLIP_SOURCE permission");

            synchronized (this) {
                checkAndSetPrimaryClipLocked(clip, callingPackage, userId, sourcePackage);
            }
        }

        @GuardedBy("this")
        private void checkAndSetPrimaryClipLocked(
                ClipData clip, String callingPackage, @UserIdInt int userId, String sourcePackage) {
            if (clip == null || clip.getItemCount() <= 0) {
                throw new IllegalArgumentException("No items");
            }
@@ -389,8 +407,7 @@ public class ClipboardService extends SystemService {
                return;
            }
            checkDataOwnerLocked(clip, intendingUid);
                setPrimaryClipInternal(clip, intendingUid, callingPackage);
            }
            setPrimaryClipInternal(clip, intendingUid, sourcePackage);
        }

        @Override
@@ -492,6 +509,26 @@ public class ClipboardService extends SystemService {
                return false;
            }
        }

        @Override
        public String getPrimaryClipSource(String callingPackage, int userId) {
            getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
                    "Requires SET_CLIP_SOURCE permission");
            synchronized (this) {
                final int intendingUid = getIntendingUid(callingPackage, userId);
                final int intendingUserId = UserHandle.getUserId(intendingUid);
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                        intendingUid, intendingUserId, false)
                        || isDeviceLocked(intendingUserId)) {
                    return null;
                }
                PerUserClipboard clipboard = getClipboard(intendingUserId);
                if (clipboard.primaryClip != null) {
                    return clipboard.mPrimaryClipPackage;
                }
                return null;
            }
        }
    };

    private PerUserClipboard getClipboard(@UserIdInt int userId) {