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

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

Merge "Added dismiss, expand, and collapse accessibility actions" into nyc-dev

parents d430f1a0 e9bad242
Loading
Loading
Loading
Loading
+32 −14
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
@@ -63,6 +64,33 @@ public class NotificationHeaderView extends ViewGroup {
            }
        }
    };
    final AccessibilityDelegate mExpandDelegate = new AccessibilityDelegate() {

        @Override
        public boolean performAccessibilityAction(View host, int action, Bundle args) {
            if (super.performAccessibilityAction(host, action, args)) {
                return true;
            }
            if (action == AccessibilityNodeInfo.ACTION_COLLAPSE
                    || action == AccessibilityNodeInfo.ACTION_EXPAND) {
                mExpandClickListener.onClick(mExpandButton);
                return true;
            }
            return false;
        }

        @Override
        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(host, info);
            // Avoid that the button description is also spoken
            info.setClassName(getClass().getName());
            if (mExpanded) {
                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
            } else {
                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
            }
        }
    };

    public NotificationHeaderView(Context context) {
        this(context, null);
@@ -92,6 +120,9 @@ public class NotificationHeaderView extends ViewGroup {
        mAppName = findViewById(com.android.internal.R.id.app_name_text);
        mHeaderText = findViewById(com.android.internal.R.id.header_text);
        mExpandButton = (ImageView) findViewById(com.android.internal.R.id.expand_button);
        if (mExpandButton != null) {
            mExpandButton.setAccessibilityDelegate(mExpandDelegate);
        }
        mIcon = findViewById(com.android.internal.R.id.icon);
        mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
    }
@@ -230,7 +261,7 @@ public class NotificationHeaderView extends ViewGroup {
    public void setOnClickListener(@Nullable OnClickListener l) {
        mExpandClickListener = l;
        setOnTouchListener(mExpandClickListener != null ? mTouchListener : null);
        setFocusable(l != null);
        mExpandButton.setOnClickListener(mExpandClickListener);
        updateTouchListener();
    }

@@ -380,19 +411,6 @@ public class NotificationHeaderView extends ViewGroup {
        return this;
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfo(info);
        if (mExpandClickListener != null) {
            AccessibilityNodeInfo.AccessibilityAction expand
                    = new AccessibilityNodeInfo.AccessibilityAction(
                    AccessibilityNodeInfo.ACTION_CLICK,
                    getContext().getString(
                            com.android.internal.R.string.expand_action_accessibility));
            info.addAction(expand);
        }
    }

    public ImageView getExpandButton() {
        return mExpandButton;
    }
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.internal.widget;

import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.RemoteViews;

/**
 * An expand button in a notification
 */
@RemoteViews.RemoteView
public class NotificationExpandButton extends ImageView {
    public NotificationExpandButton(Context context) {
        super(context);
    }

    public NotificationExpandButton(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NotificationExpandButton(Context context, @Nullable AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public NotificationExpandButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
        super.getBoundsOnScreen(outRect, clipToParent);
        extendRectToMinTouchSize(outRect);
    }

    private void extendRectToMinTouchSize(Rect rect) {
        int touchTargetSize = (int) (getResources().getDisplayMetrics().density * 48);
        rect.left = rect.centerX() - touchTargetSize / 2;
        rect.right = rect.left + touchTargetSize;
        rect.top = rect.centerY() - touchTargetSize / 2;
        rect.bottom = rect.top + touchTargetSize;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@
        android:layout="@layout/notification_template_part_chronometer"
        android:visibility="gone"
        />
    <ImageView
    <com.android.internal.widget.NotificationExpandButton
        android:id="@+id/expand_button"
        android:background="@null"
        android:layout_width="wrap_content"
+60 −4
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -37,11 +38,11 @@ import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewStub;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Chronometer;
import android.widget.ImageView;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.util.NotificationColorUtil;
import com.android.systemui.R;
@@ -50,6 +51,7 @@ import com.android.systemui.statusbar.notification.HybridNotificationView;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackScrollState;
import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.statusbar.stack.StackViewState;
@@ -148,6 +150,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
                        nowExpanded);
                logExpansionEvent(true /* userAction */, wasExpanded);
            } else {
                if (v.isAccessibilityFocused()) {
                    mPrivateLayout.setFocusOnVisibilityChange();
                }
                boolean nowExpanded;
                if (isPinned()) {
                    nowExpanded = !mExpandedWhenPinned;
@@ -180,6 +185,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
                }
    };
    private OnClickListener mOnClickListener;
    private View mChildAfterViewWhenDismissed;
    private View mGroupParentWhenDismissed;
    private boolean mRefocusOnDismiss;

    public boolean isGroupExpansionChanging() {
        if (isChildInGroup()) {
@@ -716,8 +724,19 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
        }
    }

    public void setDismissed(boolean dismissed) {
    public void setDismissed(boolean dismissed, boolean fromAccessibility) {
        mDismissed = dismissed;
        mGroupParentWhenDismissed = mNotificationParent;
        mRefocusOnDismiss = fromAccessibility;
        mChildAfterViewWhenDismissed = null;
        if (isChildInGroup()) {
            List<ExpandableNotificationRow> notificationChildren =
                    mNotificationParent.getNotificationChildren();
            int i = notificationChildren.indexOf(this);
            if (i != -1 && i < notificationChildren.size() - 1) {
                mChildAfterViewWhenDismissed = notificationChildren.get(i + 1);
            }
        }
    }

    public boolean isDismissed() {
@@ -749,6 +768,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
        return mChildrenContainer;
    }

    public View getChildAfterViewWhenDismissed() {
        return mChildAfterViewWhenDismissed;
    }

    public View getGroupParentWhenDismissed() {
        return mGroupParentWhenDismissed;
    }

    public interface ExpansionLogger {
        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
    }
@@ -1325,8 +1352,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {

    private void updateClearability() {
        // public versions cannot be dismissed
        mVetoButton.setVisibility(isClearable() && (!mShowingPublic
                || !mSensitiveHiddenInGeneral) ? View.VISIBLE : View.GONE);
        mVetoButton.setVisibility(canViewBeDismissed() ? View.VISIBLE : View.GONE);
    }

    private boolean canViewBeDismissed() {
        return isClearable() && (!mShowingPublic || !mSensitiveHiddenInGeneral);
    }

    public void makeActionsVisibile() {
@@ -1568,6 +1598,32 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
        }
    }

    @Override
    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfoInternal(info);
        if (canViewBeDismissed()) {
            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
        }
    }

    @Override
    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
        if (super.performAccessibilityActionInternal(action, arguments)) {
            return true;
        }
        switch (action) {
            case AccessibilityNodeInfo.ACTION_DISMISS:
                NotificationStackScrollLayout.performDismiss(this, mGroupManager,
                        true /* fromAccessibility */);
                return true;
        }
        return false;
    }

    public boolean shouldRefocusOnDismiss() {
        return mRefocusOnDismiss || isAccessibilityFocused();
    }

    public interface OnExpandClickListener {
        void onExpandClicked(NotificationData.Entry clickedEntry, boolean nowExpanded);
    }
+24 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.android.internal.util.NotificationColorUtil;
import com.android.systemui.R;
@@ -117,6 +118,7 @@ public class NotificationContentView extends FrameLayout {
    private PendingIntent mPreviousHeadsUpRemoteInputIntent;

    private int mContentHeightAtAnimationStart = UNDEFINED;
    private boolean mFocusOnVisibilityChange;


    public NotificationContentView(Context context, AttributeSet attrs) {
@@ -395,6 +397,19 @@ public class NotificationContentView extends FrameLayout {
        }
    }

    private void focusExpandButtonIfNecessary() {
        if (mFocusOnVisibilityChange) {
            NotificationHeaderView header = getVisibleNotificationHeader();
            if (header != null) {
                ImageView expandButton = header.getExpandButton();
                if (expandButton != null) {
                    expandButton.requestAccessibilityFocus();
                }
            }
            mFocusOnVisibilityChange = false;
        }
    }

    public void setContentHeight(int contentHeight) {
        mContentHeight = Math.max(Math.min(contentHeight, getHeight()), getMinHeight());
        selectLayout(mAnimate /* animate */, false /* force */);
@@ -584,7 +599,8 @@ public class NotificationContentView extends FrameLayout {
            updateContentTransformation();
        } else {
            int visibleType = calculateVisibleType();
            if (visibleType != mVisibleType || force) {
            boolean changedType = visibleType != mVisibleType;
            if (changedType || force) {
                View visibleView = getViewForVisibleType(visibleType);
                if (visibleView != null) {
                    visibleView.setVisibility(VISIBLE);
@@ -604,6 +620,9 @@ public class NotificationContentView extends FrameLayout {
                    updateViewVisibilities(visibleType);
                }
                mVisibleType = visibleType;
                if (changedType) {
                    focusExpandButtonIfNecessary();
                }
                updateBackgroundColor(animate);
            }
        }
@@ -1133,4 +1152,8 @@ public class NotificationContentView extends FrameLayout {
            mContentHeightAtAnimationStart = UNDEFINED;
        }
    }

    public void setFocusOnVisibilityChange() {
        mFocusOnVisibilityChange = true;
    }
}
Loading