1 /*
2  * Copyright (C) 2020 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.android.settings.accessibility.AccessibilityUtil.State.OFF;
20 import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
21 import static com.android.settings.accessibility.AutoclickUtils.KEY_DELAY_MODE;
22 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
23 
24 import static com.google.common.truth.Truth.assertThat;
25 
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.anyInt;
28 import static org.mockito.ArgumentMatchers.anyString;
29 import static org.mockito.Mockito.doReturn;
30 import static org.mockito.Mockito.never;
31 import static org.mockito.Mockito.reset;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 
35 import android.content.Context;
36 import android.content.SharedPreferences;
37 import android.provider.Settings.Secure;
38 
39 import androidx.preference.PreferenceScreen;
40 import androidx.test.core.app.ApplicationProvider;
41 
42 import com.android.settingslib.widget.LayoutPreference;
43 import com.android.settingslib.widget.SelectorWithWidgetPreference;
44 import com.android.settingslib.widget.SelectorWithWidgetPreference.OnClickListener;
45 
46 import org.junit.Rule;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 import org.mockito.Mock;
50 import org.mockito.Spy;
51 import org.mockito.junit.MockitoJUnit;
52 import org.mockito.junit.MockitoRule;
53 import org.robolectric.RobolectricTestRunner;
54 
55 /** Tests for {@link ToggleAutoclickPreferenceController}. */
56 @RunWith(RobolectricTestRunner.class)
57 public class ToggleAutoclickPreferenceControllerTest {
58 
59     private static final String KEY_PREF_DEFAULT = "accessibility_control_autoclick_default";
60     private static final String KEY_PREF_CUSTOM = "accessibility_control_autoclick_custom";
61     private static final String KEY_CUSTOM_SEEKBAR = "autoclick_custom_seekbar";
62 
63     @Rule
64     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
65     @Mock
66     private PreferenceScreen mScreen;
67     @Mock
68     private SelectorWithWidgetPreference mDelayModePref;
69     @Mock
70     private LayoutPreference mSeekBarPref;
71     @Mock
72     private SharedPreferences mSharedPreferences;
73     @Spy
74     private Context mContext = ApplicationProvider.getApplicationContext();
75     private ToggleAutoclickPreferenceController mController;
76 
77     @Test
getAvailabilityStatus_available()78     public void getAvailabilityStatus_available() {
79         setUpController(KEY_PREF_DEFAULT);
80 
81         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
82     }
83 
84     @Test
setClickListenerOnDelayModePref_whenDisplay_success()85     public void setClickListenerOnDelayModePref_whenDisplay_success() {
86         setUpController(KEY_PREF_DEFAULT);
87 
88         mController.displayPreference(mScreen);
89 
90         verify(mDelayModePref).setOnClickListener(any(OnClickListener.class));
91     }
92 
93     @Test
onStart_registerOnSharedPreferenceChangeListener()94     public void onStart_registerOnSharedPreferenceChangeListener() {
95         doReturn(mSharedPreferences).when(mContext).getSharedPreferences(anyString(), anyInt());
96         setUpController(KEY_PREF_DEFAULT);
97 
98         mController.onStart();
99 
100         verify(mSharedPreferences).registerOnSharedPreferenceChangeListener(mController);
101     }
102 
103     @Test
onStop_unregisterOnSharedPreferenceChangeListener()104     public void onStop_unregisterOnSharedPreferenceChangeListener() {
105         doReturn(mSharedPreferences).when(mContext).getSharedPreferences(anyString(), anyInt());
106         setUpController(KEY_PREF_DEFAULT);
107 
108         mController.onStop();
109 
110         verify(mSharedPreferences).unregisterOnSharedPreferenceChangeListener(mController);
111     }
112 
113     @Test
onRadioButtonClicked_offMode_disableAutoClick()114     public void onRadioButtonClicked_offMode_disableAutoClick() {
115         setUpController(KEY_PREF_DEFAULT);
116         mController.displayPreference(mScreen);
117 
118         mController.onRadioButtonClicked(mDelayModePref);
119 
120         final boolean isEnabled = Secure.getInt(mContext.getContentResolver(),
121                 Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF) == ON;
122         final int delayMs = Secure.getInt(mContext.getContentResolver(),
123                 Secure.ACCESSIBILITY_AUTOCLICK_DELAY, 0);
124         assertThat(delayMs).isEqualTo(0);
125         assertThat(isEnabled).isFalse();
126     }
127 
128 
129     @Test
onRadioButtonClicked_customMode_enableAutoClick()130     public void onRadioButtonClicked_customMode_enableAutoClick() {
131         setUpController(KEY_PREF_CUSTOM);
132         mController.displayPreference(mScreen);
133 
134         mController.onRadioButtonClicked(mDelayModePref);
135 
136         final boolean isEnabled = Secure.getInt(mContext.getContentResolver(),
137                 Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF) == ON;
138         assertThat(isEnabled).isTrue();
139     }
140 
141     @Test
onSharedPreferenceChanged_customMode_shouldShowCustomSeekbar()142     public void onSharedPreferenceChanged_customMode_shouldShowCustomSeekbar() {
143         setUpController(KEY_PREF_CUSTOM);
144         mController.displayPreference(mScreen);
145         mController.onRadioButtonClicked(mDelayModePref);
146         when(mDelayModePref.isChecked()).thenReturn(true);
147         reset(mSeekBarPref);
148 
149         mController.onSharedPreferenceChanged(mSharedPreferences, KEY_DELAY_MODE);
150 
151         verify(mSeekBarPref).setVisible(true);
152     }
153 
154     @Test
onSharedPreferenceChanged_offMode_shouldNotShowCustomSeekbar()155     public void onSharedPreferenceChanged_offMode_shouldNotShowCustomSeekbar() {
156         setUpController(KEY_PREF_DEFAULT);
157         mController.displayPreference(mScreen);
158         mController.onRadioButtonClicked(mDelayModePref);
159         reset(mSeekBarPref);
160 
161         mController.onSharedPreferenceChanged(mSharedPreferences, KEY_DELAY_MODE);
162 
163         verify(mSeekBarPref, never()).setVisible(true);
164     }
165 
setUpController(String preferenceKey)166     private void setUpController(String preferenceKey) {
167         mController = new ToggleAutoclickPreferenceController(mContext, preferenceKey);
168         when(mScreen.findPreference(preferenceKey)).thenReturn(mDelayModePref);
169         when(mDelayModePref.getKey()).thenReturn(preferenceKey);
170         when(mScreen.findPreference(KEY_CUSTOM_SEEKBAR)).thenReturn(mSeekBarPref);
171     }
172 }
173