1 /*
2  * Copyright (C) 2023 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.FlashNotificationsUtil.ACTION_FLASH_NOTIFICATION_START_PREVIEW;
20 import static com.android.settings.accessibility.FlashNotificationsUtil.EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE;
21 import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_LONG_PREVIEW;
22 import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_SHORT_PREVIEW;
23 import static com.android.settings.accessibility.ShadowFlashNotificationsUtils.setFlashNotificationsState;
24 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
25 
26 import static com.google.common.truth.Truth.assertThat;
27 
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.ArgumentMatchers.anyBoolean;
30 import static org.mockito.ArgumentMatchers.eq;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 
36 import android.content.ContentResolver;
37 import android.content.Context;
38 import android.content.Intent;
39 import android.provider.Settings;
40 
41 import androidx.lifecycle.Lifecycle;
42 import androidx.lifecycle.LifecycleOwner;
43 import androidx.preference.Preference;
44 import androidx.preference.PreferenceScreen;
45 import androidx.test.core.app.ApplicationProvider;
46 
47 import org.junit.After;
48 import org.junit.Before;
49 import org.junit.Rule;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 import org.mockito.ArgumentCaptor;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 import org.mockito.Spy;
56 import org.mockito.junit.MockitoJUnit;
57 import org.mockito.junit.MockitoRule;
58 import org.robolectric.RobolectricTestRunner;
59 import org.robolectric.annotation.Config;
60 
61 @RunWith(RobolectricTestRunner.class)
62 @Config(shadows = ShadowFlashNotificationsUtils.class)
63 public class FlashNotificationsPreviewPreferenceControllerTest {
64     private static final String PREFERENCE_KEY = "preference_key";
65 
66     @Rule
67     public MockitoRule mMockitoRule = MockitoJUnit.rule();
68     @Spy
69     private final Context mContext = ApplicationProvider.getApplicationContext();
70     @Mock
71     private PreferenceScreen mPreferenceScreen;
72     @Mock
73     private Preference mPreference;
74     @Spy
75     private ContentResolver mContentResolver = mContext.getContentResolver();
76 
77     private FlashNotificationsPreviewPreferenceController mController;
78 
79     @Before
setUp()80     public void setUp() {
81         MockitoAnnotations.initMocks(this);
82         when(mPreferenceScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
83         when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
84 
85         when(mContext.getContentResolver()).thenReturn(mContentResolver);
86         mController = new FlashNotificationsPreviewPreferenceController(mContext, PREFERENCE_KEY);
87     }
88 
89     @After
tearDown()90     public void tearDown() {
91         ShadowFlashNotificationsUtils.reset();
92     }
93 
94     @Test
testGetAvailabilityStatus()95     public void testGetAvailabilityStatus() {
96         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
97     }
98 
99     @Test
testDisplayPreference_torchPresent_cameraOff_screenOff_verifyDisabled()100     public void testDisplayPreference_torchPresent_cameraOff_screenOff_verifyDisabled() {
101         setFlashNotificationsState(FlashNotificationsUtil.State.OFF);
102 
103         mController.displayPreference(mPreferenceScreen);
104         verify(mPreference).setEnabled(eq(false));
105     }
106 
107     @Test
testDisplayPreference_torchPresent_cameraOn_screenOff_verifyEnabled()108     public void testDisplayPreference_torchPresent_cameraOn_screenOff_verifyEnabled() {
109         setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA);
110 
111         mController.displayPreference(mPreferenceScreen);
112         verify(mPreference).setEnabled(eq(true));
113     }
114 
115     @Test
testDisplayPreference_torchPresent_cameraOff_screenOn_verifyEnabled()116     public void testDisplayPreference_torchPresent_cameraOff_screenOn_verifyEnabled() {
117         setFlashNotificationsState(FlashNotificationsUtil.State.SCREEN);
118 
119         mController.displayPreference(mPreferenceScreen);
120         verify(mPreference).setEnabled(eq(true));
121     }
122 
123     @Test
testDisplayPreference_torchPresent_cameraOn_screenOn_verifyEnabled()124     public void testDisplayPreference_torchPresent_cameraOn_screenOn_verifyEnabled() {
125         setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA_SCREEN);
126 
127         mController.displayPreference(mPreferenceScreen);
128         verify(mPreference).setEnabled(eq(true));
129     }
130 
131     @Test
testHandlePreferenceTreeClick_invalidPreference()132     public void testHandlePreferenceTreeClick_invalidPreference() {
133         mController.handlePreferenceTreeClick(mock(Preference.class));
134         verify(mContext, never()).sendBroadcastAsUser(any(), any());
135     }
136 
137     @Test
handlePreferenceTreeClick_assertAction()138     public void handlePreferenceTreeClick_assertAction() {
139         mController.handlePreferenceTreeClick(mPreference);
140 
141         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
142         verify(mContext).sendBroadcastAsUser(captor.capture(), any());
143         Intent captured = captor.getValue();
144 
145         assertThat(captured.getAction()).isEqualTo(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
146     }
147 
148     @Test
handlePreferenceTreeClick_assertExtra()149     public void handlePreferenceTreeClick_assertExtra() {
150         mController.handlePreferenceTreeClick(mPreference);
151 
152         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
153         verify(mContext).sendBroadcastAsUser(captor.capture(), any());
154         Intent captured = captor.getValue();
155 
156         assertThat(captured.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE, TYPE_LONG_PREVIEW))
157                 .isEqualTo(TYPE_SHORT_PREVIEW);
158     }
159 
160     @Test
onStateChanged_onResume_cameraUri_verifyRegister()161     public void onStateChanged_onResume_cameraUri_verifyRegister() {
162         mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
163         verify(mContentResolver).registerContentObserver(
164                 eq(Settings.System.getUriFor(Settings.System.CAMERA_FLASH_NOTIFICATION)),
165                 anyBoolean(), eq(mController.mContentObserver));
166     }
167 
168     @Test
onStateChanged_onResume_screenUri_verifyRegister()169     public void onStateChanged_onResume_screenUri_verifyRegister() {
170         mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
171         verify(mContentResolver).registerContentObserver(
172                 eq(Settings.System.getUriFor(Settings.System.SCREEN_FLASH_NOTIFICATION)),
173                 anyBoolean(), eq(mController.mContentObserver));
174     }
175 
176     @Test
onStateChanged_onPause_verifyUnregister()177     public void onStateChanged_onPause_verifyUnregister() {
178         mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_PAUSE);
179         verify(mContentResolver).unregisterContentObserver(eq(mController.mContentObserver));
180     }
181 }
182