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

Commit 2bad68cd authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixed when IntelligenceManager.notifyAppeared()/disappeared() is called."

parents fa2b8557 bd5f58d8
Loading
Loading
Loading
Loading
+56 −77
Original line number Diff line number Diff line
@@ -3373,9 +3373,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *
     * |-------|-------|-------|-------|
     *                              1111 PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK
     *                             1     PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT
     *                            1      PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED
     *                           1       PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE
     *                             1     PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED
     *                            1      PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED
     * |-------|-------|-------|-------|
     */
@@ -3396,28 +3395,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * Variables used to control when the IntelligenceManager.notifyNodeAdded()/removed() methods
     * should be called.
     *
     * The idea is to call notifyNodeAdded() after the view is layout and visible, then call
     * notifyNodeRemoved() when it's gone (without known when it was removed from the parent).
     *
     * TODO(b/111276913): the current algortighm could probably be optimized and some of them
     * removed
     * The idea is to call notifyAppeared() after the view is layout and visible, then call
     * notifyDisappeared() when it's gone (without known when it was removed from the parent).
     */
    private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT = 0x10;
    private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED = 0x20;
    private static final int PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE = 0x40;
    private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED = 0x10;
    private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED = 0x20;
    /* End of masks for mPrivateFlags4 */
    private static final int CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED = 1;
    private static final int CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED = 0;
    @IntDef(flag = true, prefix = { "CONTENT_CAPTURE_NOTIFICATION_TYPE_" }, value = {
            CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED,
            CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED
    })
    @Retention(RetentionPolicy.SOURCE)
    private @interface ContentCaptureNotificationType {}
    /** @hide */
    protected static final int VIEW_STRUCTURE_FOR_ASSIST = 0;
    /** @hide */
@@ -8933,63 +8918,61 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * Helper used to notify the {@link IntelligenceManager} when the view is removed or
     * added, based on whether it's laid out and visible, and without knowing if the parent removed
     * it from the view hierarchy.
     *
     * <p>This method is called from many places (visibility changed, view laid out, view attached
     * or detached to/from window, etc...) and hence must contain the logic to call the manager, as
     * described below:
     *
     * <ol>
     *   <li>It should only be called when content capture is enabled for the view.
     *   <li>It must call viewAppeared() before viewDisappeared()
     *   <li>viewAppearead() can only be called when the view is visible and laidout
     *   <li>It should not call the same event twice.
     * </ol>
     */
    // TODO(b/111276913): make sure the current algorithm covers all cases. For example, it should
    // probably be called every time notifyEnterOrExitForAutoFillIfNeeded() is called as well.
    private void notifyNodeAddedOrRemovedForContentCaptureIfNeeded(
            @ContentCaptureNotificationType int type) {
        if (type != CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED
                && type != CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED) {
            // Sanity check so it does not screw up the flags
            Log.wtf(CONTENT_CAPTURE_LOG_TAG, "notifyNodeAddedOrRemovedForContentCaptureIfNeeded(): "
                    + "invalid type " + type + " for " + this);
            return;
        }
        if (!isImportantForContentCapture()) return;
    private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) {
        final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class);
        if (im == null || !im.isContentCaptureEnabled()) return;
        // Make sure event is notified just once, and reset the
        // PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE flag
        boolean ignoreNotification = false;
        if (type == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) {
            if ((mPrivateFlags4 & PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE)
                    == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) {
                ignoreNotification = true;
            } else {
                mPrivateFlags4 |= PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE;
            }
        } else {
            if ((mPrivateFlags4 & PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE)
                    == CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED) {
                ignoreNotification = true;
            } else {
                mPrivateFlags4 &= ~PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE;
            }
        }
        if (ignoreNotification) {
        // NOTE: isImportantForContentCapture() is more expensive than im.isContentCaptureEnabled()
        if (!isImportantForContentCapture()) return;
        if (appeared) {
            if (!isLaidOut() || !isVisibleToUser()
                    || (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0) {
                if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
                // TODO(b/111276913): remove this log statement if the algorithm is not improved
                // (right now it's called too many times when the activity is stopped and/or views
                // disappear
                Log.v(CONTENT_CAPTURE_LOG_TAG, "notifyNodeAddedOrRemovedForContentCaptureIfNeeded("
                        + type + "): ignoring repeated notification on " + this);
                    Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'appeared' on " + this + ": laid="
                            + isLaidOut() + ", visible=" + isVisibleToUser()
                            + ": alreadyNotifiedAppeared="
                            + ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0));
                }
                return;
            }
        if (type == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) {
            // All good: notify the manager...
            final ViewStructure structure = im.newViewStructure(this);
            onProvideContentCaptureStructure(structure, /* flags= */ 0);
            im.notifyViewAppeared(structure);
            mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED;
            // ...and set the flags
            mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
            mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
        } else {
            if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED) == 0) {
                return; // skip initial notification
            if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) == 0
                    || (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0) {
                if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
                    Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'disappeared' on " + this
                            + ": notifiedAppeared="
                            + ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0)
                            + ", alreadyNotifiedDisappeared=" + ((mPrivateFlags4
                                    & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0));
                }
                return;
            }
            // All good: notify the manager...
            im.notifyViewDisappeared(getAutofillId());
            // ...and set the flags
            mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
            mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
        }
    }
@@ -12896,6 +12879,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    public void dispatchStartTemporaryDetach() {
        mPrivateFlags3 |= PFLAG3_TEMPORARY_DETACH;
        notifyEnterOrExitForAutoFillIfNeeded(false);
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(false);
        onStartTemporaryDetach();
    }
@@ -12922,6 +12906,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            notifyFocusChangeToInputMethodManager(true /* hasFocus */);
        }
        notifyEnterOrExitForAutoFillIfNeeded(true);
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
    }
    /**
@@ -13503,9 +13488,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                        : AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED);
            }
        }
        notifyNodeAddedOrRemovedForContentCaptureIfNeeded(isVisible
                ? CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED
                : CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED);
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible);
    }
    /**
@@ -19076,6 +19060,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        needGlobalAttributesUpdate(false);
        notifyEnterOrExitForAutoFillIfNeeded(true);
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
    }
    @UnsupportedAppUsage
@@ -19125,8 +19110,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
        notifyEnterOrExitForAutoFillIfNeeded(false);
        notifyNodeAddedOrRemovedForContentCaptureIfNeeded(
                CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED);
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(false);
    }
    /**
@@ -21432,12 +21416,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            notifyEnterOrExitForAutoFillIfNeeded(true);
        }
        if ((mViewFlags & VISIBILITY_MASK) == VISIBLE
                && (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT) == 0) {
            notifyNodeAddedOrRemovedForContentCaptureIfNeeded(
                    CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED);
            mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT;
        }
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
    }
    private boolean hasParentWantsFocus() {
+3 −0
Original line number Diff line number Diff line
@@ -10942,6 +10942,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        if (!isPassword || viewFor == VIEW_STRUCTURE_FOR_AUTOFILL
                || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
            if (mLayout == null) {
                if (viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
                    Log.w(LOG_TAG, "onProvideContentCaptureStructure(): calling assumeLayout()");
                }
                assumeLayout();
            }
            Layout layout = mLayout;