TalkBack: Clarify volume panel slice action label
Change the generic "double-tap to activate" into "double-tap to enter settings". Bug: b/285516489 Test: atest PanelSlicesAdapterTest Change-Id: I1bba0d625c93db90f347b756f5a20a7ac7e64d56
This commit is contained in:
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
<item type="id" name="encrypt_dont_require_password" />
|
<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 -->
|
<!-- 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_up" />
|
||||||
<item type="id" name="action_drag_move_down" />
|
<item type="id" name="action_drag_move_down" />
|
||||||
|
@@ -4592,6 +4592,8 @@
|
|||||||
</ol>
|
</ol>
|
||||||
]]>
|
]]>
|
||||||
</string>
|
</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] -->
|
<!-- 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>
|
<string name="accessibility_autoclick_preference_title">Autoclick (dwell timing)</string>
|
||||||
<!-- Title for accessibility dwell timing footer. [CHAR LIMIT=NONE] -->
|
<!-- Title for accessibility dwell timing footer. [CHAR LIMIT=NONE] -->
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.panel;
|
|||||||
|
|
||||||
import static android.app.slice.Slice.HINT_ERROR;
|
import static android.app.slice.Slice.HINT_ERROR;
|
||||||
import static android.app.slice.SliceItem.FORMAT_SLICE;
|
import static android.app.slice.SliceItem.FORMAT_SLICE;
|
||||||
|
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -25,6 +26,7 @@ import android.net.Uri;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -59,12 +61,15 @@ public class PanelSlicesAdapter
|
|||||||
private final List<LiveData<Slice>> mSliceLiveData;
|
private final List<LiveData<Slice>> mSliceLiveData;
|
||||||
private final int mMetricsCategory;
|
private final int mMetricsCategory;
|
||||||
private final PanelFragment mPanelFragment;
|
private final PanelFragment mPanelFragment;
|
||||||
|
private final String mSliceClickActionLabel;
|
||||||
|
|
||||||
public PanelSlicesAdapter(
|
public PanelSlicesAdapter(
|
||||||
PanelFragment fragment, Map<Uri, LiveData<Slice>> sliceLiveData, int metricsCategory) {
|
PanelFragment fragment, Map<Uri, LiveData<Slice>> sliceLiveData, int metricsCategory) {
|
||||||
mPanelFragment = fragment;
|
mPanelFragment = fragment;
|
||||||
mSliceLiveData = new ArrayList<>(sliceLiveData.values());
|
mSliceLiveData = new ArrayList<>(sliceLiveData.values());
|
||||||
mMetricsCategory = metricsCategory;
|
mMetricsCategory = metricsCategory;
|
||||||
|
mSliceClickActionLabel = mPanelFragment.getContext().getString(
|
||||||
|
R.string.accessibility_action_label_panel_slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -78,7 +83,6 @@ public class PanelSlicesAdapter
|
|||||||
} else {
|
} else {
|
||||||
view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
|
view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SliceRowViewHolder(view);
|
return new SliceRowViewHolder(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +119,9 @@ public class PanelSlicesAdapter
|
|||||||
public class SliceRowViewHolder extends RecyclerView.ViewHolder
|
public class SliceRowViewHolder extends RecyclerView.ViewHolder
|
||||||
implements DividerItemDecoration.DividedViewHolder {
|
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
|
@VisibleForTesting
|
||||||
final SliceView sliceView;
|
final SliceView sliceView;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -135,6 +142,7 @@ public class PanelSlicesAdapter
|
|||||||
public void onBind(Slice slice) {
|
public void onBind(Slice slice) {
|
||||||
// Hides slice which reports with error hint or not contain any slice sub-item.
|
// Hides slice which reports with error hint or not contain any slice sub-item.
|
||||||
if (slice == null || !isValidSlice(slice)) {
|
if (slice == null || !isValidSlice(slice)) {
|
||||||
|
updateActionLabel();
|
||||||
sliceView.setVisibility(View.GONE);
|
sliceView.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@@ -158,6 +166,60 @@ public class PanelSlicesAdapter
|
|||||||
eventInfo.actionType /* value */);
|
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) {
|
private boolean isValidSlice(Slice slice) {
|
||||||
|
@@ -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.PanelContent.VIEW_TYPE_SLIDER;
|
||||||
import static com.android.settings.panel.PanelSlicesAdapter.MAX_NUM_OF_SLICES;
|
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.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
|
||||||
|
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_NOTIFICATION_URI;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -139,6 +140,19 @@ public class PanelSlicesAdapterTest {
|
|||||||
assertThat(viewHolder.mSliceSliderLayout).isNull();
|
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
|
@Test
|
||||||
public void onCreateViewHolder_viewTypeSlider_verifyLayout() {
|
public void onCreateViewHolder_viewTypeSlider_verifyLayout() {
|
||||||
final PanelSlicesAdapter adapter =
|
final PanelSlicesAdapter adapter =
|
||||||
|
Reference in New Issue
Block a user