diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 874e9a6deda66..44433753775eb 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -470,7 +470,7 @@ public class ClipboardService extends SystemService { synchronized (mLock) { addActiveOwnerLocked(intendingUid, pkg); PerUserClipboard clipboard = getClipboardLocked(intendingUserId); - maybeNotifyLocked(pkg, intendingUid, intendingUserId, clipboard); + showAccessNotificationLocked(pkg, intendingUid, intendingUserId, clipboard); return clipboard.primaryClip; } } @@ -934,7 +934,7 @@ public class ClipboardService extends SystemService { private boolean clipboardAccessAllowed(int op, String callingPackage, int uid, @UserIdInt int userId, boolean shouldNoteOp) { - boolean allowed = false; + boolean allowed; // First, verify package ownership to ensure use below is safe. mAppOps.checkPackage(uid, callingPackage); @@ -943,15 +943,9 @@ public class ClipboardService extends SystemService { if (mPm.checkPermission(android.Manifest.permission.READ_CLIPBOARD_IN_BACKGROUND, callingPackage) == PackageManager.PERMISSION_GRANTED) { allowed = true; - } - // The default IME is always allowed to access the clipboard. - String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, userId); - if (!TextUtils.isEmpty(defaultIme)) { - final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName(); - if (imePkg.equals(callingPackage)) { - allowed = true; - } + } else { + // The default IME is always allowed to access the clipboard. + allowed = isDefaultIme(userId, callingPackage); } switch (op) { @@ -1008,12 +1002,24 @@ public class ClipboardService extends SystemService { return appOpsResult == AppOpsManager.MODE_ALLOWED; } + private boolean isDefaultIme(int userId, String packageName) { + String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD, userId); + if (!TextUtils.isEmpty(defaultIme)) { + final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName(); + return imePkg.equals(packageName); + } + return false; + } + /** - * Potentially notifies the user (via a toast) about an app accessing the clipboard. - * TODO(b/167676460): STOPSHIP as we don't want this code as-is to launch. Just an experiment. + * Shows a toast to inform the user that an app has accessed the clipboard. This is only done if + * the setting is enabled, and if the accessing app is not the source of the data and is not the + * IME, the content capture service, or the autofill service. The notification is also only + * shown once per clip for each app. */ @GuardedBy("mLock") - private void maybeNotifyLocked(String callingPackage, int uid, @UserIdInt int userId, + private void showAccessNotificationLocked(String callingPackage, int uid, @UserIdInt int userId, PerUserClipboard clipboard) { if (clipboard.primaryClip == null) { return; @@ -1029,15 +1035,9 @@ public class ClipboardService extends SystemService { if (UserHandle.isSameApp(uid, clipboard.primaryClipUid)) { return; } - // Exclude some special cases. It's a bit wasteful to check these again here, but for now - // beneficial to have all the logic contained in this single (probably temporary) method. - String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, userId); - if (!TextUtils.isEmpty(defaultIme)) { - final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName(); - if (imePkg.equals(callingPackage)) { - return; - } + // Exclude special cases: IME, ContentCapture, Autofill. + if (isDefaultIme(userId, callingPackage)) { + return; } if (mContentCaptureInternal != null && mContentCaptureInternal.isContentCaptureServiceForUser(uid, userId)) {