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

Commit 9b65ea39 authored by Amin Shaikh's avatar Amin Shaikh
Browse files

Fix QS edit accessibility.

- Announce the correct QS tile positions when moving/adding tiles.
- Only insert a placeholder tile when adding tiles.
- Ensure all tiles are draggable, even if they are currently unavailable.
- Fix off by one error adding tiles into the last position.
- Remove tile remove a11y announcement as it is unnecessary.

Change-Id: Ia0bc1cb1559c2e46f9ddfe0f3ba0f50d5de56868
Fixes: 78608195
Fixes: 78611593
Fixes: 74253408
Test: manual
parent 90f197ef
Loading
Loading
Loading
Loading
+34 −28
Original line number Original line Diff line number Diff line
@@ -67,6 +67,10 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
    private static final long EDIT_ID = 10000;
    private static final long EDIT_ID = 10000;
    private static final long DIVIDER_ID = 20000;
    private static final long DIVIDER_ID = 20000;


    private static final int ACTION_NONE = 0;
    private static final int ACTION_ADD = 1;
    private static final int ACTION_MOVE = 2;

    private final Context mContext;
    private final Context mContext;


    private final Handler mHandler = new Handler();
    private final Handler mHandler = new Handler();
@@ -82,7 +86,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
    private List<TileInfo> mAllTiles;
    private List<TileInfo> mAllTiles;


    private Holder mCurrentDrag;
    private Holder mCurrentDrag;
    private boolean mAccessibilityMoving;
    private int mAccessibilityAction = ACTION_NONE;
    private int mAccessibilityFromIndex;
    private int mAccessibilityFromIndex;
    private QSTileHost mHost;
    private QSTileHost mHost;


@@ -172,7 +176,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta


    @Override
    @Override
    public int getItemViewType(int position) {
    public int getItemViewType(int position) {
        if (mAccessibilityMoving && position == mEditIndex - 1) {
        if (mAccessibilityAction == ACTION_ADD && position == mEditIndex - 1) {
            return TYPE_ACCESSIBLE_DROP;
            return TYPE_ACCESSIBLE_DROP;
        }
        }
        if (position == mTileDividerIndex) {
        if (position == mTileDividerIndex) {
@@ -266,18 +270,18 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
        if (position > mEditIndex) {
        if (position > mEditIndex) {
            info.state.contentDescription = mContext.getString(
            info.state.contentDescription = mContext.getString(
                    R.string.accessibility_qs_edit_add_tile_label, info.state.label);
                    R.string.accessibility_qs_edit_add_tile_label, info.state.label);
        } else if (mAccessibilityMoving) {
        } else if (mAccessibilityAction != ACTION_NONE) {
            info.state.contentDescription = mContext.getString(
            info.state.contentDescription = mContext.getString(
                    R.string.accessibility_qs_edit_position_label, position + 1);
                    R.string.accessibility_qs_edit_position_label, position + 1);
        } else {
        } else {
            info.state.contentDescription = mContext.getString(
            info.state.contentDescription = mContext.getString(
                    R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label);
                    R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label);
        }
        }
        holder.mTileView.onStateChanged(info.state);
        holder.mTileView.handleStateChanged(info.state);
        holder.mTileView.setShowAppLabel(position > mEditIndex && !info.isSystem);
        holder.mTileView.setShowAppLabel(position > mEditIndex && !info.isSystem);


        if (mAccessibilityManager.isTouchExplorationEnabled()) {
        if (mAccessibilityManager.isTouchExplorationEnabled()) {
            final boolean selectable = !mAccessibilityMoving || position < mEditIndex;
            final boolean selectable = mAccessibilityAction == ACTION_NONE || position < mEditIndex;
            holder.mTileView.setClickable(selectable);
            holder.mTileView.setClickable(selectable);
            holder.mTileView.setFocusable(selectable);
            holder.mTileView.setFocusable(selectable);
            holder.mTileView.setImportantForAccessibility(selectable
            holder.mTileView.setImportantForAccessibility(selectable
@@ -288,13 +292,13 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
                    @Override
                    @Override
                    public void onClick(View v) {
                    public void onClick(View v) {
                        int position = holder.getAdapterPosition();
                        int position = holder.getAdapterPosition();
                        if (mAccessibilityMoving) {
                        if (mAccessibilityAction != ACTION_NONE) {
                            selectPosition(position, v);
                            selectPosition(position, v);
                        } else {
                        } else {
                            if (position < mEditIndex && canRemoveTiles()) {
                            if (position < mEditIndex && canRemoveTiles()) {
                                showAccessibilityDialog(position, v);
                                showAccessibilityDialog(position, v);
                            } else {
                            } else {
                                startAccessibleDrag(position);
                                startAccessibleAdd(position);
                            }
                            }
                        }
                        }
                    }
                    }
@@ -308,15 +312,15 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
    }
    }


    private void selectPosition(int position, View v) {
    private void selectPosition(int position, View v) {
        if (mAccessibilityAction == ACTION_ADD) {
            // Remove the placeholder.
            // Remove the placeholder.
        mAccessibilityMoving = false;
            mTiles.remove(mEditIndex--);
            mTiles.remove(mEditIndex--);
        notifyItemRemoved(mEditIndex - 1);
            notifyItemRemoved(mEditIndex);
            // Don't remove items when the last position is selected.
            // Don't remove items when the last position is selected.
        if (position == mEditIndex) position--;
            if (position == mEditIndex - 1) position--;

        }
        mAccessibilityAction = ACTION_NONE;
        move(mAccessibilityFromIndex, position, v);
        move(mAccessibilityFromIndex, position, v);

        notifyDataSetChanged();
        notifyDataSetChanged();
    }
    }


@@ -331,7 +335,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
                    @Override
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == 0) {
                        if (which == 0) {
                            startAccessibleDrag(position);
                            startAccessibleMove(position);
                        } else {
                        } else {
                            move(position, info.isSystem ? mEditIndex : mTileDividerIndex, v);
                            move(position, info.isSystem ? mEditIndex : mTileDividerIndex, v);
                            notifyItemChanged(mTileDividerIndex);
                            notifyItemChanged(mTileDividerIndex);
@@ -345,12 +349,18 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
        dialog.show();
        dialog.show();
    }
    }


    private void startAccessibleDrag(int position) {
    private void startAccessibleAdd(int position) {
        mAccessibilityMoving = true;
        mNeedsFocus = true;
        mAccessibilityFromIndex = position;
        mAccessibilityFromIndex = position;
        mAccessibilityAction = ACTION_ADD;
        // Add placeholder for last slot.
        // Add placeholder for last slot.
        mTiles.add(mEditIndex++, null);
        mTiles.add(mEditIndex++, null);
        mNeedsFocus = true;
        notifyDataSetChanged();
    }

    private void startAccessibleMove(int position) {
        mAccessibilityFromIndex = position;
        mAccessibilityAction = ACTION_MOVE;
        notifyDataSetChanged();
        notifyDataSetChanged();
    }
    }


@@ -365,30 +375,26 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
        CharSequence fromLabel = mTiles.get(from).state.label;
        CharSequence fromLabel = mTiles.get(from).state.label;
        move(from, to, mTiles);
        move(from, to, mTiles);
        updateDividerLocations();
        updateDividerLocations();
        CharSequence announcement;
        if (to >= mEditIndex) {
        if (to >= mEditIndex) {
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE_SPEC,
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE_SPEC,
                    strip(mTiles.get(to)));
                    strip(mTiles.get(to)));
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE,
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE,
                    from);
                    from);
            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_removed,
                    fromLabel);
        } else if (from >= mEditIndex) {
        } else if (from >= mEditIndex) {
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD_SPEC,
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD_SPEC,
                    strip(mTiles.get(to)));
                    strip(mTiles.get(to)));
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD,
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD,
                    to);
                    to);
            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_added,
            v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_added,
                    fromLabel, (to + 1));
                    fromLabel, (to + 1)));
        } else {
        } else {
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE_SPEC,
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE_SPEC,
                    strip(mTiles.get(to)));
                    strip(mTiles.get(to)));
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE,
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE,
                    to);
                    to);
            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_moved,
            v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_moved,
                    fromLabel, (to + 1));
                    fromLabel, (to + 1)));
        }
        }
        v.announceForAccessibility(announcement);
        saveSpecs(mHost);
        saveSpecs(mHost);
        return true;
        return true;
    }
    }