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

Commit a5b314b9 authored by Behnam Heydarshahi's avatar Behnam Heydarshahi Committed by Android (Google) Code Review
Browse files

Merge "TalkBack: Clarify volume panel slice action label" into udc-qpr-dev

parents 6c70c5ec 017fa1c6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@

    <item type="id" name="encrypt_dont_require_password" />

    <item type="id" name="tag_row_view" />

    <!-- Used for custom accessibility actions in the Drag-and-Drop locale list -->
    <item type="id" name="action_drag_move_up" />
    <item type="id" name="action_drag_move_down" />
+2 −0
Original line number Diff line number Diff line
@@ -4607,6 +4607,8 @@
        </ol>
        ]]>
    </string>
    <!-- suffixed to click action texts "Double-tap to " -->
    <string name="accessibility_action_label_panel_slice">enter settings</string>
    <!-- Title for accessibility preference for configuring feature that performs click action soon after mouse/trackpad pointer stops moving. [CHAR LIMIT=NONE] -->
    <string name="accessibility_autoclick_preference_title">Autoclick (dwell timing)</string>
    <!-- Title for accessibility dwell timing footer. [CHAR LIMIT=NONE] -->
+63 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settings.panel;

import static android.app.slice.Slice.HINT_ERROR;
import static android.app.slice.SliceItem.FORMAT_SLICE;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;

import android.app.settings.SettingsEnums;
import android.content.Context;
@@ -25,6 +26,7 @@ import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
@@ -59,12 +61,15 @@ public class PanelSlicesAdapter
    private final List<LiveData<Slice>> mSliceLiveData;
    private final int mMetricsCategory;
    private final PanelFragment mPanelFragment;
    private final String mSliceClickActionLabel;

    public PanelSlicesAdapter(
            PanelFragment fragment, Map<Uri, LiveData<Slice>> sliceLiveData, int metricsCategory) {
        mPanelFragment = fragment;
        mSliceLiveData = new ArrayList<>(sliceLiveData.values());
        mMetricsCategory = metricsCategory;
        mSliceClickActionLabel = mPanelFragment.getContext().getString(
                R.string.accessibility_action_label_panel_slice);
    }

    @NonNull
@@ -78,7 +83,6 @@ public class PanelSlicesAdapter
        } else {
            view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
        }

        return new SliceRowViewHolder(view);
    }

@@ -115,6 +119,9 @@ public class PanelSlicesAdapter
    public class SliceRowViewHolder extends RecyclerView.ViewHolder
            implements DividerItemDecoration.DividedViewHolder {

        private static final int ROW_VIEW_ID = androidx.slice.view.R.id.row_view;
        private static final int ROW_VIEW_TAG = R.id.tag_row_view;

        @VisibleForTesting
        final SliceView sliceView;
        @VisibleForTesting
@@ -135,6 +142,7 @@ public class PanelSlicesAdapter
        public void onBind(Slice slice) {
            // Hides slice which reports with error hint or not contain any slice sub-item.
            if (slice == null || !isValidSlice(slice)) {
                updateActionLabel();
                sliceView.setVisibility(View.GONE);
                return;
            } else {
@@ -158,6 +166,60 @@ public class PanelSlicesAdapter
                                        eventInfo.actionType /* value */);
                    })
            );
            updateActionLabel();
        }

        /**
         * Either set the action label if the row view is inflated into Slice, or set a listener to
         * do so later when the row is available.
         */
        @VisibleForTesting void updateActionLabel() {
            if (sliceView == null) {
                return;
            }

            final LinearLayout llRow = sliceView.findViewById(ROW_VIEW_ID);
            if (llRow != null) {
                // Just set the label for the row. if is already laid out, there is no need for
                // listening to future changes.
                setActionLabel(llRow);
            } else { // set the accessibility delegate when row_view is laid out
                Object alreadyAddedListener = sliceView.getTag(ROW_VIEW_TAG);
                if (alreadyAddedListener != null) {
                    return;
                }
                sliceView.setTag(ROW_VIEW_TAG, new Object());

                sliceView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                    @Override
                    public void onLayoutChange(View v, int left, int top, int right, int bottom,
                            int oldLeft, int oldTop, int oldRight, int oldBottom) {
                        LinearLayout row = sliceView.findViewById(ROW_VIEW_ID);
                        if (row != null) {
                            setActionLabel(row);
                            sliceView.removeOnLayoutChangeListener(this);
                        }
                    }
                });
            }
        }

        /**
         * Update the action label for TalkBack to be more specific
         * @param view the RowView within the Slice
         */
        private void setActionLabel(View view) {
            view.setAccessibilityDelegate(new View.AccessibilityDelegate() {
                @Override
                public void onInitializeAccessibilityNodeInfo(View host,
                        AccessibilityNodeInfo info) {
                    super.onInitializeAccessibilityNodeInfo(host, info);
                    AccessibilityNodeInfo.AccessibilityAction customClick =
                            new AccessibilityNodeInfo.AccessibilityAction(
                                    ACTION_CLICK, mSliceClickActionLabel);
                    info.addAction(customClick);
                }
            });
        }

        private boolean isValidSlice(Slice slice) {
+14 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.settings.panel;
import static com.android.settings.panel.PanelContent.VIEW_TYPE_SLIDER;
import static com.android.settings.panel.PanelSlicesAdapter.MAX_NUM_OF_SLICES;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_NOTIFICATION_URI;

import static com.google.common.truth.Truth.assertThat;

@@ -139,6 +140,19 @@ public class PanelSlicesAdapterTest {
        assertThat(viewHolder.mSliceSliderLayout).isNull();
    }

    @Test
    public void onCreateViewHolder_viewTypeSlider_verifyActionLabelSet() {
        addTestLiveData(VOLUME_NOTIFICATION_URI);

        final PanelSlicesAdapter adapter =
                new PanelSlicesAdapter(mPanelFragment, mData, 0);
        final ViewGroup view = new FrameLayout(mContext);
        SliceRowViewHolder viewHolder = spy(adapter.onCreateViewHolder(view, 0 /* view type*/));
        adapter.onBindViewHolder(viewHolder, 0);

        verify(viewHolder).updateActionLabel();
    }

    @Test
    public void onCreateViewHolder_viewTypeSlider_verifyLayout() {
        final PanelSlicesAdapter adapter =