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

Commit fa6ac6f3 authored by Yuhan Yang's avatar Yuhan Yang
Browse files

Polish click timeout setting

Update delay before click time options and put it in a dialog.

screenshot: go/screenshot-aw7momh848qghqj

No-Typo-Check: pre-existing typo, will fix it in a separate cl.
Bug: 390460859
Test: atest ToggleAutoclickDelayBeforeClickControllerTest
Flag: com.android.server.accessibility.enable_autoclick_indicator
Change-Id: Id0574bd4f1c272a6aa56f9b947d734ecd804bf46
parent c6aa5cb8
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright 2025 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.
-->

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal">

    <TextView
        android:id="@+id/autoclick_delay_before_click_dialog_title"
        android:text="@string/autoclick_delay_before_click_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginHorizontal="26dp"
        android:textSize="20sp"
        android:textColor="?android:attr/textColorPrimary"
        android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
        app:layout_constraintBottom_toTopOf="@+id/autoclick_delay_before_click_dialog_subtitle"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
    />

    <TextView
        android:id="@+id/autoclick_delay_before_click_dialog_subtitle"
        android:text="@string/autoclick_delay_before_click_summary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="26dp"
        android:layout_marginTop="8dp"
        android:textSize="16sp"
        android:textColor="?android:attr/textColorSecondary"
        app:layout_constraintBottom_toTopOf="@+id/autoclick_delay_before_click_value_group"
        app:layout_constraintTop_toBottomOf="@+id/autoclick_delay_before_click_dialog_title"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
    />

    <RadioGroup
        android:id="@+id/autoclick_delay_before_click_value_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@+id/autoclick_delay_before_click_dialog_subtitle"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <RadioButton
            android:id="@+id/accessibility_autoclick_dialog_600ms"
            style="@style/AutoclickDialogRadioButton"/>
        <RadioButton
            android:id="@+id/accessibility_autoclick_dialog_800ms"
            style="@style/AutoclickDialogRadioButton"/>
        <RadioButton
            android:id="@+id/accessibility_autoclick_dialog_1sec"
            style="@style/AutoclickDialogRadioButton"/>
        <RadioButton
            android:id="@+id/accessibility_autoclick_dialog_2sec"
            style="@style/AutoclickDialogRadioButton"/>
        <RadioButton
            android:id="@+id/accessibility_autoclick_dialog_4sec"
            style="@style/AutoclickDialogRadioButton"/>
    </RadioGroup>

</androidx.constraintlayout.widget.ConstraintLayout>
 No newline at end of file
+6 −0
Original line number Diff line number Diff line
@@ -5752,6 +5752,12 @@
    <!-- Title for the toggle button that turns on/off the autoclick shortcut. [CHAR_LIMIT=NONE] -->
    <!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
    <string name="accessibility_autoclick_shortcut_title" translatable="false">Autoclick shortcut</string>
    <!-- Title for the alert dialog that adjust the time for the mouse to hover before autoclick performs. [CHAR_LIMIT=NONE] -->
    <!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
    <string name="autoclick_delay_before_click_title" translatable="false">Delay before click</string>
    <!-- Summary for the alert dialog that adjust the time for the mouse to hover before autoclick performs. [CHAR_LIMIT=NONE] -->
    <!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
    <string name="autoclick_delay_before_click_summary" translatable="false">Time it takes to click after the cursor stops moving</string>
    <!-- Title for the alert dialog that adjust auto click cursor area size. [CHAR_LIMIT=NONE] -->
    <!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
    <string name="autoclick_cursor_area_size_title" translatable="false">Click area</string>
+6 −0
Original line number Diff line number Diff line
@@ -86,6 +86,12 @@
        settings:searchable="false"
        settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController"/>

    <Preference
        android:key="accessibility_control_autoclick_delay_before_click"
        android:persistent="false"
        android:title="@string/autoclick_delay_before_click_title"
        settings:controller="com.android.settings.accessibility.ToggleAutoclickDelayBeforeClickController"/>

    <Preference
        android:key="accessibility_control_autoclick_cursor_area_size"
        android:persistent="false"
+131 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.settings.accessibility;

import static android.view.accessibility.AccessibilityManager.AUTOCLICK_DELAY_DEFAULT;

import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;

import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;

import com.google.common.collect.ImmutableBiMap;

/**
 * Fragment for creating a dialog in autoclick settings.
 */
public class AutoclickDelayDialogFragment extends InstrumentedDialogFragment {

    private static final String TAG = AutoclickDelayDialogFragment.class.getSimpleName();

    public final ImmutableBiMap<Integer, Integer> RADIO_BUTTON_ID_TO_DELAY_TIME =
            new ImmutableBiMap.Builder<Integer, Integer>()
                .put(R.id.accessibility_autoclick_dialog_600ms, 600)
                .put(R.id.accessibility_autoclick_dialog_800ms, 800)
                .put(R.id.accessibility_autoclick_dialog_1sec, 1000)
                .put(R.id.accessibility_autoclick_dialog_2sec, 2000)
                .put(R.id.accessibility_autoclick_dialog_4sec, 4000)
                .buildOrThrow();

    /** Create an AutoclickDelayDialogFragment instance. */
    public static @NonNull AutoclickDelayDialogFragment newInstance() {
        return new AutoclickDelayDialogFragment();
    }

    public int getMetricsCategory() {
        return SettingsEnums.ACCESSIBILITY_TOGGLE_AUTOCLICK;
    }

    @Override
    public @NonNull Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        View dialogView = LayoutInflater.from(getContext())
                .inflate(R.layout.dialog_autoclick_delay_before_click, /* root= */ null);
        getRadioButtonLabels(dialogView);
        RadioGroup radioGroup = dialogView.findViewById(
                R.id.autoclick_delay_before_click_value_group);

        AlertDialog alertDialog = new AlertDialog.Builder(getContext())
                .setView(dialogView)
                .setPositiveButton(android.R.string.ok,
                        (dialog, which) -> {
                            int checkedRadioButtonId =
                                    radioGroup.getCheckedRadioButtonId();

                            // TODO(b/390460859): Update AUTOCLICK_DELAY_DEFAULT value to 1 sec.
                            int delay = AUTOCLICK_DELAY_DEFAULT;
                            if (RADIO_BUTTON_ID_TO_DELAY_TIME
                                    .containsKey(checkedRadioButtonId)) {
                                delay = RADIO_BUTTON_ID_TO_DELAY_TIME.get(checkedRadioButtonId);
                            }

                            // TODO(b/390460859): Add custom seekbar for other delay time values.
                            updateAutoclickDelay(delay);
                        })
                .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss())
                .create();

        if (savedInstanceState == null) {
            initStateBasedOnDelay(radioGroup);
        }

        return alertDialog;
    }

    private void initStateBasedOnDelay(@NonNull RadioGroup radioGroup) {
        // TODO(b/390460859): Add custom seekbar for other delay time values.
        final int autoclickDelay = Settings.Secure.getInt(getContext().getContentResolver(),
                Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
                AccessibilityManager.AUTOCLICK_DELAY_DEFAULT);

        Integer radioButtonId = RADIO_BUTTON_ID_TO_DELAY_TIME.inverse().get(autoclickDelay);
        if (radioButtonId != null) {
            radioGroup.check(radioButtonId);
        }
    }

    private void getRadioButtonLabels(@NonNull View dialogView) {
        for (Integer radioButtonId : RADIO_BUTTON_ID_TO_DELAY_TIME.keySet()) {
            RadioButton radioButton = dialogView.findViewById(radioButtonId);
            if (radioButton != null) {
                radioButton.setText(AutoclickUtils.getAutoclickDelaySummary(
                        getContext(), R.string.accessibilty_autoclick_delay_unit_second,
                        RADIO_BUTTON_ID_TO_DELAY_TIME.get(radioButtonId)));
            }
        }
    }

    /** Updates autoclick delay time. */
    public void updateAutoclickDelay(int delay) {
        Settings.Secure.putInt(
                getContext().getContentResolver(),
                Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
                delay);
    }
}
+8 −4
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.settings.accessibility;
import android.annotation.StringRes;
import android.content.Context;

import androidx.annotation.NonNull;

import com.android.settingslib.utils.StringUtil;

import java.util.HashMap;
@@ -47,6 +49,7 @@ public final class AutoclickUtils {

    /**
     * Gets string that should be used for provided autoclick delay.
     * Omit the decimal when delay time represents an integer.
     *
     * @param context context from which string should be retrieved.
     * @param id The desired resource identifier, as generated by the aapt
@@ -54,11 +57,12 @@ public final class AutoclickUtils {
     *           entry. The value 0 is an invalid identifier.
     * @param delayMillis Delay for whose value summary should be retrieved.
     */
    public static CharSequence getAutoclickDelaySummary(Context context,
    public static @NonNull CharSequence getAutoclickDelaySummary(
                @NonNull Context context,
                @StringRes int id, int delayMillis) {
        final float delaySecond =  (float) delayMillis / 1000;
        // Only show integer when delay time is 1.
        final String decimalFormat = (delaySecond == 1) ? "%.0f" : "%.1f";
        // Omit the decimal when delay time represents an integer.
        final String decimalFormat = (delaySecond == (int) (delaySecond)) ? "%.0f" : "%.1f";

        Map<String, Object> arguments = new HashMap<>();
        arguments.put("count", delaySecond);
Loading