Merge "Refactor SettingsContentObserver and add it to follow typing feature."
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/** Test for {@link AccessibilitySettingsContentObserver}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilitySettingsContentObserverTest {
|
||||
|
||||
private static final String SPECIFIC_KEY_A_1 = "SPECIFIC_KEY_A_1";
|
||||
private static final String SPECIFIC_KEY_A_2 = "SPECIFIC_KEY_A_2";
|
||||
private static final String SPECIFIC_KEY_B_1 = "SPECIFIC_KEY_B_1";
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final AccessibilitySettingsContentObserver mObserver =
|
||||
new AccessibilitySettingsContentObserver(new Handler());
|
||||
private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackA =
|
||||
spy(new TestableContentObserverCallback());
|
||||
private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackB =
|
||||
spy(new TestableContentObserverCallback());
|
||||
private final ContentResolver mContentResolver = mContext.getContentResolver();
|
||||
|
||||
@Test
|
||||
public void register_shouldRegisterContentObserverForDefaultKeys() {
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unregister_shouldUnregisterContentObserver() {
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.unregister(mContentResolver);
|
||||
|
||||
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
|
||||
assertNotObserverToUri(shadowContentResolver, Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
assertNotObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void register_addSpecificKeys_shouldRegisterContentObserverForSpecificAndDefaultKeys() {
|
||||
mObserver.registerKeysToObserverCallback(List.of(SPECIFIC_KEY_A_1), mObserverCallbackA);
|
||||
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
|
||||
assertObserverToUri(shadowContentResolver, SPECIFIC_KEY_A_1, mObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_shouldTriggerCallbackOnDefaultKey() {
|
||||
mObserver.registerObserverCallback(mObserverCallbackA);
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.onChange(/* selfChange= */ false,
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED));
|
||||
|
||||
verify(mObserverCallbackA).onChange(Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_registerSpecificKeys_shouldTriggerSpecificCallback() {
|
||||
mObserver.registerKeysToObserverCallback(
|
||||
List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.onChange(/* selfChange= */ false,
|
||||
Settings.Secure.getUriFor(SPECIFIC_KEY_A_2));
|
||||
|
||||
verify(mObserverCallbackA).onChange(SPECIFIC_KEY_A_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_registerSpecificKeys_withoutTriggerOtherCallback() {
|
||||
mObserver.registerKeysToObserverCallback(
|
||||
List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
|
||||
mObserver.registerKeysToObserverCallback(
|
||||
List.of(SPECIFIC_KEY_B_1), mObserverCallbackB);
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.onChange(/* selfChange= */ false,
|
||||
Settings.Secure.getUriFor(SPECIFIC_KEY_B_1));
|
||||
|
||||
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_1);
|
||||
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_2);
|
||||
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_B_1);
|
||||
verify(mObserverCallbackB).onChange(SPECIFIC_KEY_B_1);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mObserver.unregister(mContentResolver);
|
||||
}
|
||||
|
||||
private void assertNotObserverToUri(ShadowContentResolver resolver, String key) {
|
||||
assertThat(resolver.getContentObservers(Settings.Secure.getUriFor(key))).isEmpty();
|
||||
}
|
||||
|
||||
private void assertObserverToUri(ShadowContentResolver resolver,
|
||||
String key, ContentObserver observer) {
|
||||
Collection<ContentObserver> observers =
|
||||
resolver.getContentObservers(Settings.Secure.getUriFor(key));
|
||||
assertThat(observers).contains(observer);
|
||||
}
|
||||
|
||||
private static class TestableContentObserverCallback implements
|
||||
AccessibilitySettingsContentObserver.ContentObserverCallback {
|
||||
@Override
|
||||
public void onChange(String key) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
@@ -281,10 +281,10 @@ public class AccessibilitySettingsTest {
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
|
||||
anyBoolean(),
|
||||
any(SettingsContentObserver.class));
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
verify(mContentResolver).registerContentObserver(eq(Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)), anyBoolean(),
|
||||
any(SettingsContentObserver.class));
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
verify(mActivity, atLeast(1)).registerReceiver(any(PackageMonitor.class), captor.capture(),
|
||||
isNull(), any());
|
||||
intentFilter = captor.getAllValues().get(/* first time */ 0);
|
||||
@@ -301,7 +301,8 @@ public class AccessibilitySettingsTest {
|
||||
|
||||
mFragment.onDestroy();
|
||||
|
||||
verify(mContentResolver).unregisterContentObserver(any(SettingsContentObserver.class));
|
||||
verify(mContentResolver).unregisterContentObserver(
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
verify(mActivity).unregisterReceiver(any(PackageMonitor.class));
|
||||
|
||||
}
|
||||
|
@@ -94,4 +94,15 @@ public class MagnificationFollowTypingPreferenceControllerTest {
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
assertThat(mSwitchPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_disableFollowTyping_shouldReturnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), KEY_FOLLOW_TYPING, OFF);
|
||||
|
||||
mController.updateState();
|
||||
|
||||
verify(mSwitchPreference).setChecked(false);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
assertThat(mSwitchPreference.isChecked()).isFalse();
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,8 @@ import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -27,6 +29,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
@@ -75,12 +78,16 @@ public class ToggleFeaturePreferenceFragmentTest {
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
|
||||
|
||||
private TestToggleFeaturePreferenceFragment mFragment;
|
||||
private PreferenceScreen mScreen;
|
||||
private Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceManager mPreferenceManager;
|
||||
|
||||
@Mock
|
||||
private FragmentActivity mActivity;
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
|
||||
@Before
|
||||
public void setUpTestFragment() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -89,9 +96,11 @@ public class ToggleFeaturePreferenceFragmentTest {
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
mScreen = spy(new PreferenceScreen(mContext, null));
|
||||
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
doReturn(mScreen).when(mFragment).getPreferenceScreen();
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
when(mActivity.getContentResolver()).thenReturn(mContentResolver);
|
||||
final PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
|
||||
when(screen.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
doReturn(screen).when(mFragment).getPreferenceScreen();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,6 +112,25 @@ public class ToggleFeaturePreferenceFragmentTest {
|
||||
verify(mFragment).addPreferencesFromResource(R.xml.placeholder_prefs);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {ShadowFragment.class})
|
||||
public void onResume_haveRegisterToSpecificUris() {
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(Bundle.EMPTY);
|
||||
|
||||
mFragment.onResume();
|
||||
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
|
||||
eq(false),
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)),
|
||||
eq(false),
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
|
||||
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
|
||||
|
@@ -25,14 +25,15 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
@@ -63,8 +64,8 @@ import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@@ -96,17 +97,22 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
|
||||
private Context mContext;
|
||||
private Resources mResources;
|
||||
|
||||
@Mock
|
||||
private FragmentActivity mActivity;
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
|
||||
@Before
|
||||
public void setUpTestFragment() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
|
||||
mFragment = spy(new TestToggleScreenMagnificationPreferenceFragment(mContext));
|
||||
mResources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mFragment.getContext().getResources()).thenReturn(mResources);
|
||||
doReturn(activity).when(mFragment).getActivity();
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
when(mActivity.getContentResolver()).thenReturn(mContentResolver);
|
||||
}
|
||||
|
||||
@Ignore("Ignore it since a NPE is happened in ShadowWindowManagerGlobal. (Ref. b/214161063)")
|
||||
@@ -142,6 +148,30 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
|
||||
assertThat(switchPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {ShadowFragment.class})
|
||||
public void onResume_haveRegisterToSpecificUris() {
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(Bundle.EMPTY);
|
||||
|
||||
mFragment.onResume();
|
||||
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
|
||||
eq(false),
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)),
|
||||
eq(false),
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED)),
|
||||
eq(false),
|
||||
any(AccessibilitySettingsContentObserver.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasValueInSettings_putValue_hasValue() {
|
||||
setMagnificationTripleTapEnabled(/* enabled= */ true);
|
||||
|
Reference in New Issue
Block a user