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

Commit 5b1a00e8 authored by Lyn Han's avatar Lyn Han Committed by android-build-merger
Browse files

Merge "Talkback for focus on collapsed bubble stack" into qt-dev am: 43605432

am: 169ab54a

Change-Id: Id3a349f4030d8081248acc4b68a218bbbbf3806a
parents 41993254 169ab54a
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.systemui.bubbles;

import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.view.LayoutInflater;

@@ -37,6 +40,7 @@ class Bubble {

    private final String mKey;
    private final String mGroupId;
    private String mAppName;
    private final BubbleExpandedView.OnBubbleBlockedListener mListener;

    private boolean mInflated;
@@ -45,6 +49,7 @@ class Bubble {
    BubbleExpandedView expandedView;
    private long mLastUpdated;
    private long mLastAccessed;
    private PackageManager mPm;

    public static String groupId(NotificationEntry entry) {
        UserHandle user = entry.notification.getUser();
@@ -53,16 +58,33 @@ class Bubble {

    /** Used in tests when no UI is required. */
    @VisibleForTesting(visibility = PRIVATE)
    Bubble(NotificationEntry e) {
        this (e, null);
    Bubble(Context context, NotificationEntry e) {
        this (context, e, null);
    }

    Bubble(NotificationEntry e, BubbleExpandedView.OnBubbleBlockedListener listener) {
    Bubble(Context context, NotificationEntry e,
            BubbleExpandedView.OnBubbleBlockedListener listener) {
        entry = e;
        mKey = e.key;
        mLastUpdated = e.notification.getPostTime();
        mGroupId = groupId(e);
        mListener = listener;

        mPm = context.getPackageManager();
        ApplicationInfo info;
        try {
            info = mPm.getApplicationInfo(
                entry.notification.getPackageName(),
                PackageManager.MATCH_UNINSTALLED_PACKAGES
                    | PackageManager.MATCH_DISABLED_COMPONENTS
                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                    | PackageManager.MATCH_DIRECT_BOOT_AWARE);
            if (info != null) {
                mAppName = String.valueOf(mPm.getApplicationLabel(info));
            }
        } catch (PackageManager.NameNotFoundException unused) {
            mAppName = entry.notification.getPackageName();
        }
    }

    public String getKey() {
@@ -77,6 +99,10 @@ class Bubble {
        return entry.notification.getPackageName();
    }

    public String getAppName() {
        return mAppName;
    }

    boolean isInflated() {
        return mInflated;
    }
@@ -97,9 +123,9 @@ class Bubble {

        expandedView = (BubbleExpandedView) inflater.inflate(
                R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
        expandedView.setEntry(entry, stackView);

        expandedView.setEntry(entry, stackView, mAppName);
        expandedView.setOnBlockedListener(mListener);

        mInflated = true;
    }

+16 −18
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
            if (shouldCollapse) {
                collapseStack();
            }
            updateVisibility();
            updateStack();
        }
    }

@@ -534,10 +534,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
            }
        }

        // Runs on state change.
        @Override
        public void apply() {
            mNotificationEntryManager.updateNotifications();
            updateVisibility();
            updateStack();

            if (DEBUG) {
                Log.d(TAG, "[BubbleData]");
@@ -554,34 +555,31 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
    };

    /**
     * Lets any listeners know if bubble state has changed.
     * Updates the visibility of the bubbles based on current state.
     * Does not un-bubble, just hides or un-hides. Notifies any
     * {@link BubbleStateChangeListener}s of visibility changes.
     * Updates stack description for TalkBack focus.
     */
    private void updateBubblesShowing() {
    public void updateStack() {
        if (mStackView == null) {
            return;
        }
        if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) {
            // Bubbles only appear in unlocked shade
            mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE);
        } else if (mStackView != null) {
            mStackView.setVisibility(INVISIBLE);
        }

        // Let listeners know if bubble state changed.
        boolean hadBubbles = mStatusBarWindowController.getBubblesShowing();
        boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE;
        mStatusBarWindowController.setBubblesShowing(hasBubblesShowing);
        if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) {
            mStateChangeListener.onHasBubblesChanged(hasBubblesShowing);
        }
    }

    /**
     * Updates the visibility of the bubbles based on current state.
     * Does not un-bubble, just hides or un-hides. Will notify any
     * {@link BubbleStateChangeListener}s if visibility changes.
     */
    public void updateVisibility() {
        if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) {
            // Bubbles only appear in unlocked shade
            mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE);
        } else if (mStackView != null) {
            mStackView.setVisibility(INVISIBLE);
        }
        updateBubblesShowing();
        mStackView.updateContentDescription();
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ public class BubbleData {
        Bubble bubble = getBubbleWithKey(entry.key);
        if (bubble == null) {
            // Create a new bubble
            bubble = new Bubble(entry, this::onBubbleBlocked);
            bubble = new Bubble(mContext, entry, this::onBubbleBlocked);
            doAdd(bubble);
            trim();
        } else {
+3 −4
Original line number Diff line number Diff line
@@ -244,9 +244,10 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
    /**
     * Sets the notification entry used to populate this view.
     */
    public void setEntry(NotificationEntry entry, BubbleStackView stackView) {
    public void setEntry(NotificationEntry entry, BubbleStackView stackView, String appName) {
        mStackView = stackView;
        mEntry = entry;
        mAppName = appName;

        ApplicationInfo info;
        try {
@@ -257,12 +258,10 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                            | PackageManager.MATCH_DIRECT_BOOT_AWARE);
            if (info != null) {
                mAppName = String.valueOf(mPm.getApplicationLabel(info));
                mAppIcon = mPm.getApplicationIcon(info);
            }
        } catch (PackageManager.NameNotFoundException e) {
            // Ahh... just use package name
            mAppName = entry.notification.getPackageName();
            // Do nothing.
        }
        if (mAppIcon == null) {
            mAppIcon = mPm.getDefaultActivityIcon();
+38 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.app.Notification;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.ColorMatrix;
@@ -553,6 +554,43 @@ public class BubbleStackView extends FrameLayout {
        return false;
    }

    /**
     * Update content description for a11y TalkBack.
     */
    public void updateContentDescription() {
        if (mBubbleData.getBubbles().isEmpty()) {
            return;
        }
        Bubble topBubble = mBubbleData.getBubbles().get(0);
        String appName = topBubble.getAppName();
        Notification notification = topBubble.entry.notification.getNotification();
        CharSequence titleCharSeq = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
        String titleStr = getResources().getString(R.string.stream_notification);
        if (titleCharSeq != null) {
            titleStr = titleCharSeq.toString();
        }
        int moreCount = mBubbleContainer.getChildCount() - 1;

        // Example: Title from app name.
        String singleDescription = getResources().getString(
                R.string.bubble_content_description_single, titleStr, appName);

        // Example: Title from app name and 4 more.
        String stackDescription = getResources().getString(
                R.string.bubble_content_description_stack, titleStr, appName, moreCount);

        if (mIsExpanded) {
            // TODO(b/129522932) - update content description for each bubble in expanded view.
        } else {
            // Collapsed stack.
            if (moreCount > 0) {
                mBubbleContainer.setContentDescription(stackDescription);
            } else {
                mBubbleContainer.setContentDescription(singleDescription);
            }
        }
    }

    private void updateSystemGestureExcludeRects() {
        // Exclude the region occupied by the first BubbleView in the stack
        Rect excludeZone = mSystemGestureExclusionRects.get(0);
Loading