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

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

Merge "Call OnPrimaryClipChanged when classification status changes." into sc-dev am: b74c7adf

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

Change-Id: I486bd3ef11ffcdade9202dd530f65ee217535f75
parents 236e9131 b74c7adf
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -100,6 +100,10 @@ public class ClipboardManager extends android.text.ClipboardManager {
        /**
         * Callback that is invoked by {@link android.content.ClipboardManager} when the primary
         * clip changes.
         *
         * <p>This is called when the result of {@link ClipDescription#getClassificationStatus()}
         * changes, as well as when new clip data is set. So in cases where text classification is
         * performed, this callback may be invoked multiple times for the same clip.
         */
        void onPrimaryClipChanged();
    }
+53 −11
Original line number Diff line number Diff line
@@ -606,6 +606,10 @@ public class ClipboardService extends SystemService {
                description.setTimestamp(System.currentTimeMillis());
            }
        }
        sendClipChangedBroadcast(clipboard);
    }

    private void sendClipChangedBroadcast(PerUserClipboard clipboard) {
        final long ident = Binder.clearCallingIdentity();
        final int n = clipboard.primaryClipListeners.beginBroadcast();
        try {
@@ -632,7 +636,8 @@ public class ClipboardService extends SystemService {

    @GuardedBy("mLock")
    private void startClassificationLocked(@NonNull ClipData clip, @UserIdInt int userId) {
        if (clip.getItemCount() == 0) {
        CharSequence text = (clip.getItemCount() == 0) ? null : clip.getItemAt(0).getText();
        if (TextUtils.isEmpty(text) || text.length() > mMaxClassificationLength) {
            clip.getDescription().setClassificationStatus(
                    ClipDescription.CLASSIFICATION_NOT_PERFORMED);
            return;
@@ -650,20 +655,17 @@ public class ClipboardService extends SystemService {
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        CharSequence text = clip.getItemAt(0).getText();
        if (TextUtils.isEmpty(text) || text.length() > mMaxClassificationLength
                || text.length() > classifier.getMaxGenerateLinksTextLength()) {
        if (text.length() > classifier.getMaxGenerateLinksTextLength()) {
            clip.getDescription().setClassificationStatus(
                    ClipDescription.CLASSIFICATION_NOT_PERFORMED);
            return;
        }
        getClipboardLocked(userId).mTextClassifier = classifier;
        mWorkerHandler.post(() -> doClassification(text, clip, classifier));
        mWorkerHandler.post(() -> doClassification(text, clip, classifier, userId));
    }

    @WorkerThread
    private void doClassification(
            CharSequence text, ClipData clip, TextClassifier classifier) {
            CharSequence text, ClipData clip, TextClassifier classifier, @UserIdInt int userId) {
        TextLinks.Request request = new TextLinks.Request.Builder(text).build();
        TextLinks links = classifier.generateLinks(request);

@@ -680,11 +682,51 @@ public class ClipboardService extends SystemService {
        }

        synchronized (mLock) {
            clip.getDescription().setConfidenceScores(confidences);
            PerUserClipboard clipboard = getClipboardLocked(userId);
            if (clipboard.primaryClip == clip) {
                applyClassificationAndSendBroadcastLocked(
                        clipboard, confidences, links, classifier);

                // Also apply to related profiles if needed
                List<UserInfo> related = getRelatedProfiles(userId);
                if (related != null) {
                    int size = related.size();
                    for (int i = 0; i < size; i++) {
                        int id = related.get(i).id;
                        if (id != userId) {
                            final boolean canCopyIntoProfile = !hasRestriction(
                                    UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, id);
                            if (canCopyIntoProfile) {
                                PerUserClipboard relatedClipboard = getClipboardLocked(id);
                                if (hasTextLocked(relatedClipboard, text)) {
                                    applyClassificationAndSendBroadcastLocked(
                                            relatedClipboard, confidences, links, classifier);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    @GuardedBy("mLock")
    private void applyClassificationAndSendBroadcastLocked(
            PerUserClipboard clipboard, ArrayMap<String, Float> confidences, TextLinks links,
            TextClassifier classifier) {
        clipboard.mTextClassifier = classifier;
        clipboard.primaryClip.getDescription().setConfidenceScores(confidences);
        if (!links.getLinks().isEmpty()) {
                clip.getItemAt(0).setTextLinks(links);
            clipboard.primaryClip.getItemAt(0).setTextLinks(links);
        }
        sendClipChangedBroadcast(clipboard);
    }

    @GuardedBy("mLock")
    private boolean hasTextLocked(PerUserClipboard clipboard, @NonNull CharSequence text) {
        return clipboard.primaryClip != null
                && clipboard.primaryClip.getItemCount() > 0
                && text.equals(clipboard.primaryClip.getItemAt(0).getText());
    }

    private boolean isDeviceLocked(@UserIdInt int userId) {