Add observer to autoclick main switch controller

Add an observer in ToggleAutoclickMainSwitchPreferenceController
so when the autoclick is toggled on/off at somewhere else such as
autoclick shortcut, the main switch will change accordingly.

screen cast:
go/screencast-njawnjqynzi2ode1mzm0nhxmztqwmddjzc03oa

Bug: 391416057
Test: verified manually
Flag: com.android.server.accessibility.enable_autoclick_indicator
Change-Id: I6e2a3af55cbd3f03b4feeb268b84510fc55518bf
This commit is contained in:
Yuhan Yang
2025-03-10 21:21:53 +00:00
parent 52c57d003e
commit a8eecd48d9
2 changed files with 80 additions and 1 deletions

View File

@@ -21,9 +21,19 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.server.accessibility.Flags; import com.android.server.accessibility.Flags;
import com.android.settings.R; import com.android.settings.R;
@@ -31,9 +41,24 @@ import com.android.settings.core.TogglePreferenceController;
/** The controller to handle main switch to turn on or turn off accessibility autoclick. */ /** The controller to handle main switch to turn on or turn off accessibility autoclick. */
public class ToggleAutoclickMainSwitchPreferenceController public class ToggleAutoclickMainSwitchPreferenceController
extends TogglePreferenceController { extends TogglePreferenceController implements DefaultLifecycleObserver {
static final Uri ACCESSIBILITY_AUTOCLICK_ENABLED_URI =
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED);
private final ContentResolver mContentResolver; private final ContentResolver mContentResolver;
private @Nullable Preference mPreference;
@VisibleForTesting
final ContentObserver mSettingsObserver =
new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange, @Nullable Uri uri) {
if (mPreference == null || uri == null) {
return;
}
updateState(mPreference);
}
};
public ToggleAutoclickMainSwitchPreferenceController( public ToggleAutoclickMainSwitchPreferenceController(
@NonNull Context context, @NonNull String preferenceKey) { @NonNull Context context, @NonNull String preferenceKey) {
@@ -46,6 +71,12 @@ public class ToggleAutoclickMainSwitchPreferenceController
return Flags.enableAutoclickIndicator() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; return Flags.enableAutoclickIndicator() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
} }
@Override
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
}
@Override @Override
public boolean isChecked() { public boolean isChecked() {
return Settings.Secure.getInt(mContentResolver, return Settings.Secure.getInt(mContentResolver,
@@ -61,6 +92,19 @@ public class ToggleAutoclickMainSwitchPreferenceController
return true; return true;
} }
@Override
public void onStart(@NonNull LifecycleOwner owner) {
mContentResolver.registerContentObserver(
ACCESSIBILITY_AUTOCLICK_ENABLED_URI,
/* notifyForDescendants= */ false,
mSettingsObserver);
}
@Override
public void onStop(@NonNull LifecycleOwner owner) {
mContentResolver.unregisterContentObserver(mSettingsObserver);
}
@Override @Override
public int getSliceHighlightMenuRes() { public int getSliceHighlightMenuRes() {
return R.string.menu_key_system; return R.string.menu_key_system;

View File

@@ -16,6 +16,9 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
@@ -26,15 +29,19 @@ import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings; import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowContentResolver;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class ToggleAutoclickMainSwitchPreferenceControllerTest { public class ToggleAutoclickMainSwitchPreferenceControllerTest {
@@ -43,11 +50,20 @@ public class ToggleAutoclickMainSwitchPreferenceControllerTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext(); private final Context mContext = ApplicationProvider.getApplicationContext();
private ShadowContentResolver mShadowContentResolver;
private ToggleAutoclickMainSwitchPreferenceController mController; private ToggleAutoclickMainSwitchPreferenceController mController;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
@Before @Before
public void setUp() { public void setUp() {
mShadowContentResolver = Shadow.extract(mContext.getContentResolver());
mController = new ToggleAutoclickMainSwitchPreferenceController(mContext, PREFERENCE_KEY); mController = new ToggleAutoclickMainSwitchPreferenceController(mContext, PREFERENCE_KEY);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mLifecycle.addObserver(mController);
} }
@Test @Test
@@ -80,4 +96,23 @@ public class ToggleAutoclickMainSwitchPreferenceControllerTest {
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF)) Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF))
.isEqualTo(OFF); .isEqualTo(OFF);
} }
@Test
public void onStart_shouldRegisterContentObserver() {
mLifecycle.handleLifecycleEvent(ON_START);
assertThat(mShadowContentResolver.getContentObservers(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED)))
.hasSize(1);
}
@Test
public void onStop_shouldUnregisterContentObserver() {
mLifecycle.handleLifecycleEvent(ON_START);
mLifecycle.handleLifecycleEvent(ON_STOP);
assertThat(mShadowContentResolver.getContentObservers(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED)))
.isEmpty();
}
} }