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

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

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

parents 2dc6bda3 6c40fe70
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