• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.accessibility;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.never;
22 import static org.mockito.Mockito.spy;
23 import static org.mockito.Mockito.verify;
24 
25 import android.content.ContentResolver;
26 import android.content.Context;
27 import android.database.ContentObserver;
28 import android.os.Handler;
29 import android.provider.Settings;
30 
31 import androidx.test.core.app.ApplicationProvider;
32 
33 import org.junit.After;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.robolectric.RobolectricTestRunner;
37 import org.robolectric.shadow.api.Shadow;
38 import org.robolectric.shadows.ShadowContentResolver;
39 
40 import java.util.Collection;
41 import java.util.List;
42 
43 /** Test for {@link AccessibilitySettingsContentObserver}. */
44 @RunWith(RobolectricTestRunner.class)
45 public class AccessibilitySettingsContentObserverTest {
46 
47     private static final String SPECIFIC_KEY_A_1 = "SPECIFIC_KEY_A_1";
48     private static final String SPECIFIC_KEY_A_2 = "SPECIFIC_KEY_A_2";
49     private static final String SPECIFIC_KEY_B_1 = "SPECIFIC_KEY_B_1";
50 
51     private final Context mContext = ApplicationProvider.getApplicationContext();
52     private final AccessibilitySettingsContentObserver mObserver =
53             new AccessibilitySettingsContentObserver(new Handler());
54     private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackA =
55             spy(new TestableContentObserverCallback());
56     private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackB =
57             spy(new TestableContentObserverCallback());
58     private final ContentResolver mContentResolver = mContext.getContentResolver();
59 
60     @Test
register_shouldRegisterContentObserverForDefaultKeys()61     public void register_shouldRegisterContentObserverForDefaultKeys() {
62         mObserver.register(mContentResolver);
63 
64         ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
65         assertObserverToUri(shadowContentResolver,
66                 Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
67         assertObserverToUri(shadowContentResolver,
68                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
69     }
70 
71     @Test
unregister_shouldUnregisterContentObserver()72     public void unregister_shouldUnregisterContentObserver() {
73         mObserver.register(mContentResolver);
74 
75         mObserver.unregister(mContentResolver);
76 
77         ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
78         assertNotObserverToUri(shadowContentResolver, Settings.Secure.ACCESSIBILITY_ENABLED);
79         assertNotObserverToUri(shadowContentResolver,
80                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
81     }
82 
83     @Test
register_addSpecificKeys_shouldRegisterContentObserverForSpecificAndDefaultKeys()84     public void register_addSpecificKeys_shouldRegisterContentObserverForSpecificAndDefaultKeys() {
85         mObserver.registerKeysToObserverCallback(List.of(SPECIFIC_KEY_A_1), mObserverCallbackA);
86 
87         mObserver.register(mContentResolver);
88 
89         ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
90         assertObserverToUri(shadowContentResolver,
91                 Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
92         assertObserverToUri(shadowContentResolver,
93                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
94         assertObserverToUri(shadowContentResolver, SPECIFIC_KEY_A_1, mObserver);
95     }
96 
97     @Test
onChange_shouldTriggerCallbackOnDefaultKey()98     public void onChange_shouldTriggerCallbackOnDefaultKey() {
99         mObserver.registerObserverCallback(mObserverCallbackA);
100         mObserver.register(mContentResolver);
101 
102         mObserver.onChange(/* selfChange= */ false,
103                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED));
104 
105         verify(mObserverCallbackA).onChange(Settings.Secure.ACCESSIBILITY_ENABLED);
106     }
107 
108     @Test
onChange_registerSpecificKeys_shouldTriggerSpecificCallback()109     public void onChange_registerSpecificKeys_shouldTriggerSpecificCallback() {
110         mObserver.registerKeysToObserverCallback(
111                 List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
112         mObserver.register(mContentResolver);
113 
114         mObserver.onChange(/* selfChange= */ false,
115                 Settings.Secure.getUriFor(SPECIFIC_KEY_A_2));
116 
117         verify(mObserverCallbackA).onChange(SPECIFIC_KEY_A_2);
118     }
119 
120     @Test
onChange_registerSpecificKeys_withoutTriggerOtherCallback()121     public void onChange_registerSpecificKeys_withoutTriggerOtherCallback() {
122         mObserver.registerKeysToObserverCallback(
123                 List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
124         mObserver.registerKeysToObserverCallback(
125                 List.of(SPECIFIC_KEY_B_1), mObserverCallbackB);
126         mObserver.register(mContentResolver);
127 
128         mObserver.onChange(/* selfChange= */ false,
129                 Settings.Secure.getUriFor(SPECIFIC_KEY_B_1));
130 
131         verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_1);
132         verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_2);
133         verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_B_1);
134         verify(mObserverCallbackB).onChange(SPECIFIC_KEY_B_1);
135     }
136 
137     @After
tearDown()138     public void tearDown() {
139         mObserver.unregister(mContentResolver);
140     }
141 
assertNotObserverToUri(ShadowContentResolver resolver, String key)142     private void assertNotObserverToUri(ShadowContentResolver resolver, String key) {
143         assertThat(resolver.getContentObservers(Settings.Secure.getUriFor(key))).isEmpty();
144     }
145 
assertObserverToUri(ShadowContentResolver resolver, String key, ContentObserver observer)146     private void assertObserverToUri(ShadowContentResolver resolver,
147             String key, ContentObserver observer) {
148         Collection<ContentObserver> observers =
149                 resolver.getContentObservers(Settings.Secure.getUriFor(key));
150         assertThat(observers).contains(observer);
151     }
152 
153     private static class TestableContentObserverCallback implements
154             AccessibilitySettingsContentObserver.ContentObserverCallback {
155         @Override
onChange(String key)156         public void onChange(String key) {
157             // do nothing
158         }
159     }
160 }
161