Implement Flash Notifications UI for Settings app.

Bug: 237628564
Test: make RunSettingsRoboTests ROBOTEST_FILTER=CameraFlashNotificationPreferenceControllerTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=ColorSelectorLayoutTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=FlashNotificationsPreferenceControllerTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=FlashNotificationsPreferenceFragmentTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=FlashNotificationsPreviewPreferenceControllerTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=FlashNotificationsPreviewPreferenceTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=FlashNotificationsUtilTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=ScreenFlashNotificationColorDialogFragmentTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=ScreenFlashNotificationColorTest
Change-Id: I0987590ddfcfd0873ec419db263f6a7eade81844
Signed-off-by: yw.bae <yw.bae@samsung.corp-partner.google.com>
Signed-off-by: Angela Wang <angelala@google.com>
This commit is contained in:
yw.bae
2023-01-06 22:49:14 +09:00
committed by Thomas Lin
parent 8750e58ed6
commit f763c25c1e
68 changed files with 4058 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2023 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.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowFlashNotificationsUtils.class)
public class CameraFlashNotificationPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private CameraFlashNotificationPreferenceController mController;
private ContentResolver mContentResolver;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContentResolver = mContext.getContentResolver();
mController = new CameraFlashNotificationPreferenceController(mContext, PREFERENCE_KEY);
}
@After
public void tearDown() {
ShadowFlashNotificationsUtils.reset();
}
@Test
public void getAvailabilityStatus_torchAvailable_assertAvailable() {
ShadowFlashNotificationsUtils.setIsTorchAvailable(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_torchUnavailable_assertUnsupportedOnDevice() {
ShadowFlashNotificationsUtils.setIsTorchAvailable(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void isChecked_setOff_assertFalse() {
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_setOn_assertTrue() {
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_setTrue_assertNotZero() {
mController.setChecked(true);
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION,
0)).isNotEqualTo(0);
}
@Test
public void setChecked_setFalse_assertNotOne() {
mController.setChecked(false);
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION,
1)).isNotEqualTo(1);
}
@Test
public void getSliceHighlightMenuRes() {
mController.getSliceHighlightMenuRes();
assertThat(mController.getSliceHighlightMenuRes())
.isEqualTo(R.string.menu_key_accessibility);
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 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 android.content.Context;
import android.graphics.Color;
import androidx.annotation.ColorInt;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ColorSelectorLayoutTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
ColorSelectorLayout mColorSelectorLayout;
@ColorInt
int mCheckedColor = Color.TRANSPARENT;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mColorSelectorLayout = new ColorSelectorLayout(mContext);
mColorSelectorLayout.setOnCheckedChangeListener(
layout -> mCheckedColor = layout.getCheckedColor(Color.TRANSPARENT));
}
@Test
public void setColor_checkColorChanged() {
mColorSelectorLayout.setCheckedColor(ScreenFlashNotificationColor.AZURE.mColorInt);
assertThat(mCheckedColor)
.isEqualTo(ScreenFlashNotificationColor.AZURE.mColorInt);
}
@Test
public void getCheckedColor_defaultValue() {
assertThat(mColorSelectorLayout.getCheckedColor(0xFF000000))
.isEqualTo(0xFF000000);
}
@Test
public void setSelectedColor_checkColorChanged() {
mColorSelectorLayout.setCheckedColor(ScreenFlashNotificationColor.AZURE.mColorInt);
assertThat(mColorSelectorLayout.getCheckedColor(0xFF000000))
.isEqualTo(ScreenFlashNotificationColor.AZURE.mColorInt);
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C) 2023 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.android.settings.accessibility.ShadowFlashNotificationsUtils.setFlashNotificationsState;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowFlashNotificationsUtils.class)
public class FlashNotificationsPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private FlashNotificationsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new FlashNotificationsPreferenceController(mContext, PREFERENCE_KEY);
}
@After
public void tearDown() {
ShadowFlashNotificationsUtils.reset();
}
@Test
public void getAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getSummary_stateOff_assertOff() {
setFlashNotificationsState(FlashNotificationsUtil.State.OFF);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_off));
}
@Test
public void getSummary_stateCamera_assertCamera() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_on_camera));
}
@Test
public void getSummary_stateScreen_assertScreen() {
setFlashNotificationsState(FlashNotificationsUtil.State.SCREEN);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_on_screen));
}
@Test
public void getSummary_stateCameraScreen_assertCameraScreen() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA_SCREEN);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_on_camera_and_screen));
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2023 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.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class FlashNotificationsPreferenceFragmentTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private FlashNotificationsPreferenceFragment mFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFragment = new FlashNotificationsPreferenceFragment();
}
@Test
public void getPreferenceScreenResId_isFlashNotificationsSettings() {
assertThat(mFragment.getPreferenceScreenResId())
.isEqualTo(R.xml.flash_notifications_settings);
}
@Test
public void getLogTag_isSpecifyTag() {
assertThat(mFragment.getLogTag()).isEqualTo("FlashNotificationsPreferenceFragment");
}
@Test
public void getMetricsCategory_isZero() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(0); // TODO
}
@Test
public void onAttach_attachedTheTestFragment() {
ScreenFlashNotificationPreferenceController controller = mock(
ScreenFlashNotificationPreferenceController.class);
TestFlashNotificationsPreferenceFragment testFragment =
new TestFlashNotificationsPreferenceFragment(controller);
testFragment.onAttach(mContext);
verify(controller).setParentFragment(eq(testFragment));
}
@Test
public void getHelpResource_isExpectedResource() {
assertThat(mFragment.getHelpResource())
.isEqualTo(R.string.help_url_flash_notifications);
}
static class TestFlashNotificationsPreferenceFragment extends
FlashNotificationsPreferenceFragment {
final AbstractPreferenceController mController;
TestFlashNotificationsPreferenceFragment(AbstractPreferenceController controller) {
mController = controller;
}
@Override
protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
return (T) mController;
}
}
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright (C) 2023 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.android.settings.accessibility.FlashNotificationsUtil.ACTION_FLASH_NOTIFICATION_START_PREVIEW;
import static com.android.settings.accessibility.FlashNotificationsUtil.EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE;
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_LONG_PREVIEW;
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_SHORT_PREVIEW;
import static com.android.settings.accessibility.ShadowFlashNotificationsUtils.setFlashNotificationsState;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowFlashNotificationsUtils.class)
public class FlashNotificationsPreviewPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private PreferenceScreen mPreferenceScreen;
@Mock
private Preference mPreference;
@Spy
private ContentResolver mContentResolver = mContext.getContentResolver();
private FlashNotificationsPreviewPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mPreferenceScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
mController = new FlashNotificationsPreviewPreferenceController(mContext, PREFERENCE_KEY);
}
@After
public void tearDown() {
ShadowFlashNotificationsUtils.reset();
}
@Test
public void testGetAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void testDisplayPreference_torchPresent_cameraOff_screenOff_verifyDisabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.OFF);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(false));
}
@Test
public void testDisplayPreference_torchPresent_cameraOn_screenOff_verifyEnabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(true));
}
@Test
public void testDisplayPreference_torchPresent_cameraOff_screenOn_verifyEnabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.SCREEN);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(true));
}
@Test
public void testDisplayPreference_torchPresent_cameraOn_screenOn_verifyEnabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA_SCREEN);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(true));
}
@Ignore
@Test
public void testHandlePreferenceTreeClick_invalidPreference() {
mController.handlePreferenceTreeClick(mock(Preference.class));
verify(mContext, never()).sendBroadcast(any());
}
@Test
public void handlePreferenceTreeClick_assertAction() {
mController.handlePreferenceTreeClick(mPreference);
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).sendBroadcast(captor.capture());
Intent captured = captor.getValue();
assertThat(captured.getAction()).isEqualTo(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
}
@Test
public void handlePreferenceTreeClick_assertExtra() {
mController.handlePreferenceTreeClick(mPreference);
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).sendBroadcast(captor.capture());
Intent captured = captor.getValue();
assertThat(captured.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE, TYPE_LONG_PREVIEW))
.isEqualTo(TYPE_SHORT_PREVIEW);
}
@Test
public void onStateChanged_onResume_cameraUri_verifyRegister() {
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
verify(mContentResolver).registerContentObserver(
eq(Settings.System.getUriFor(SETTING_KEY_CAMERA_FLASH_NOTIFICATION)), anyBoolean(),
eq(mController.mContentObserver));
}
@Test
public void onStateChanged_onResume_screenUri_verifyRegister() {
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
verify(mContentResolver).registerContentObserver(
eq(Settings.System.getUriFor(SETTING_KEY_SCREEN_FLASH_NOTIFICATION)), anyBoolean(),
eq(mController.mContentObserver));
}
@Test
public void onStateChanged_onPause_verifyUnregister() {
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_PAUSE);
verify(mContentResolver).unregisterContentObserver(eq(mController.mContentObserver));
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 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 android.content.Context;
import android.util.AttributeSet;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class FlashNotificationsPreviewPreferenceTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private final AttributeSet mAttributeSet = Robolectric.buildAttributeSet().build();
@Test
public void constructor_assertLayoutResource_P00() {
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
mContext);
assertThat(preference.getLayoutResource())
.isEqualTo(R.layout.flash_notification_preview_preference);
}
@Test
public void constructor_assertLayoutResource_P01() {
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
mContext, mAttributeSet);
assertThat(preference.getLayoutResource())
.isEqualTo(R.layout.flash_notification_preview_preference);
}
@Test
public void constructor_assertLayoutResource_P02() {
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
mContext, mAttributeSet, 0);
assertThat(preference.getLayoutResource())
.isEqualTo(R.layout.flash_notification_preview_preference);
}
@Test
public void constructor_assertLayoutResource_P03() {
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
mContext, mAttributeSet, 0, 0);
assertThat(preference.getLayoutResource())
.isEqualTo(R.layout.flash_notification_preview_preference);
}
}

View File

@@ -0,0 +1,220 @@
/*
* Copyright (C) 2023 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 android.hardware.camera2.CameraCharacteristics.FLASH_INFO_AVAILABLE;
import static android.hardware.camera2.CameraCharacteristics.LENS_FACING;
import static android.hardware.camera2.CameraCharacteristics.LENS_FACING_BACK;
import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT;
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
import static com.android.settings.accessibility.FlashNotificationsUtil.getColorDescriptionText;
import static com.android.settings.accessibility.FlashNotificationsUtil.getFlashNotificationsState;
import static com.android.settings.accessibility.FlashNotificationsUtil.getScreenColor;
import static com.android.settings.accessibility.FlashNotificationsUtil.isTorchAvailable;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.when;
import static org.robolectric.shadow.api.Shadow.extract;
import static org.robolectric.shadows.ShadowCameraCharacteristics.newCameraCharacteristics;
import android.content.ContentResolver;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowCameraCharacteristics;
import org.robolectric.shadows.ShadowCameraManager;
@RunWith(RobolectricTestRunner.class)
public class FlashNotificationsUtilTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private CameraManager mCameraManager = mContext.getSystemService(CameraManager.class);
private ShadowCameraManager mShadowCameraManager;
private ContentResolver mContentResolver;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mShadowCameraManager = Shadows.shadowOf(mCameraManager);
mContentResolver = mContext.getContentResolver();
}
@Test
public void isTorchAvailable_nullCameraManager_assertFalse() {
when(mContext.getSystemService(CameraManager.class)).thenReturn(null);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_noCamera_assertFalse() {
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_getCameraIdListThrowException_assertFalse()
throws CameraAccessException {
when(mCameraManager.getCameraIdList()).thenThrow(CameraAccessException.class);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_getCameraCharacteristicsThrowException_assertFalse()
throws CameraAccessException {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
mShadowCameraManager.addCamera("0", cameraCharacteristics);
when(mCameraManager.getCameraCharacteristics("0")).thenThrow(CameraAccessException.class);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_torchNotPresent_assertFalse() {
setTorchNotPresent();
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_torchPresent_assertTrue() {
setTorchPresent();
assertThat(isTorchAvailable(mContext)).isTrue();
}
@Test
public void isTorchAvailable_lensFacingFront_assertFalse() {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics);
shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, true);
shadowCameraCharacteristics.set(LENS_FACING, LENS_FACING_FRONT);
mShadowCameraManager.addCamera("0", cameraCharacteristics);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void getScreenColor_undefinedColor_throwException() {
assertThrows(FlashNotificationsUtil.ScreenColorNotFoundException.class, () ->
getScreenColor(0x4D0000FF));
}
@Test
public void getScreenColor_azureColor_returnAzure() throws Exception {
assertThat(getScreenColor(0x4D0000FF)).isEqualTo(ScreenFlashNotificationColor.AZURE);
}
@Test
public void getColorDescriptionText_undefinedColor_returnEmpty() {
assertThat(getColorDescriptionText(mContext, 0x4D0000FF)).isEqualTo("");
}
@Test
public void getColorDescriptionText_azureColor_returnAzureName() {
assertThat(getColorDescriptionText(mContext, ScreenFlashNotificationColor.AZURE.mColorInt))
.isEqualTo(mContext.getString(ScreenFlashNotificationColor.AZURE.mStringRes));
}
@Test
public void getFlashNotificationsState_torchPresent_cameraOff_screenOff_assertOff() {
setTorchPresent();
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0);
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.OFF);
}
@Test
public void getFlashNotificationsState_torchNotPresent_cameraOn_screenOff_assertOff() {
setTorchNotPresent();
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.OFF);
}
@Test
public void getFlashNotificationsState_torchPresent_cameraOn_screenOff_assertCamera() {
setTorchPresent();
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.CAMERA);
}
@Test
public void getFlashNotificationsState_torchPresent_cameraOff_screenOn_assertScreen() {
setTorchPresent();
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0);
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 1);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.SCREEN);
}
@Test
public void testGetFlashNotificationsState_torchPresent_cameraOn_screenOn_assertCameraScreen() {
setTorchPresent();
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 1);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.CAMERA_SCREEN);
}
private void setTorchPresent() {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics);
shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, true);
shadowCameraCharacteristics.set(LENS_FACING, LENS_FACING_BACK);
mShadowCameraManager.addCamera("0", cameraCharacteristics);
}
private void setTorchNotPresent() {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics);
shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, false);
mShadowCameraManager.addCamera("0", cameraCharacteristics);
}
}

View File

@@ -0,0 +1,196 @@
/*
* Copyright (C) 2023 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 android.content.DialogInterface.BUTTON_NEGATIVE;
import static android.content.DialogInterface.BUTTON_NEUTRAL;
import static android.content.DialogInterface.BUTTON_POSITIVE;
import static com.android.settings.accessibility.FlashNotificationsUtil.ACTION_FLASH_NOTIFICATION_START_PREVIEW;
import static com.android.settings.accessibility.FlashNotificationsUtil.ACTION_FLASH_NOTIFICATION_STOP_PREVIEW;
import static com.android.settings.accessibility.FlashNotificationsUtil.EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR;
import static com.android.settings.accessibility.FlashNotificationsUtil.EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE;
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_LONG_PREVIEW;
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_SHORT_PREVIEW;
import static com.android.settings.accessibility.ScreenFlashNotificationColor.AZURE;
import static com.android.settings.accessibility.ScreenFlashNotificationColor.BLUE;
import static com.android.settings.accessibility.ScreenFlashNotificationColor.CYAN;
import static com.android.settings.accessibility.ScreenFlashNotificationColor.ROSE;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.Intent;
import android.graphics.Color;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowContextWrapper;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class ScreenFlashNotificationColorDialogFragmentTest {
private ShadowContextWrapper mShadowContextWrapper;
private ScreenFlashNotificationColorDialogFragment mDialogFragment;
private AlertDialog mAlertDialog;
private ColorSelectorLayout mColorSelectorLayout;
private int mCurrentColor;
@Before
public void setUp() {
FragmentActivity fragmentActivity = Robolectric.setupActivity(FragmentActivity.class);
mShadowContextWrapper = shadowOf(fragmentActivity);
mCurrentColor = ROSE.mColorInt;
mDialogFragment = ScreenFlashNotificationColorDialogFragment.getInstance(
mCurrentColor, selectedColor -> mCurrentColor = selectedColor
);
mDialogFragment.show(fragmentActivity.getSupportFragmentManager(), "test");
mAlertDialog = (AlertDialog) mDialogFragment.getDialog();
if (mAlertDialog != null) {
mColorSelectorLayout = mAlertDialog.findViewById(R.id.color_selector_preference);
}
}
@Test
public void test_assertShow() {
assertThat(mAlertDialog.isShowing()).isTrue();
}
@Test
public void clickNeutral_assertShow() {
performClickOnDialog(BUTTON_NEUTRAL);
assertThat(mAlertDialog.isShowing()).isTrue();
}
@Test
public void clickNeutral_assertStartPreview() throws InterruptedException {
performClickOnDialog(BUTTON_NEUTRAL);
Thread.sleep(100);
Intent captured = getLastCapturedIntent();
assertThat(captured.getAction()).isEqualTo(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
assertThat(captured.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE, TYPE_SHORT_PREVIEW))
.isEqualTo(TYPE_LONG_PREVIEW);
assertThat(captured.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR, Color.TRANSPARENT))
.isEqualTo(ROSE.mColorInt);
}
@Test
public void clickNegative_assertNotShow() {
performClickOnDialog(BUTTON_NEGATIVE);
assertThat(mAlertDialog.isShowing()).isFalse();
}
@Test
public void clickPositive_assertNotShow() {
performClickOnDialog(BUTTON_POSITIVE);
assertThat(mAlertDialog.isShowing()).isFalse();
}
@Test
public void clickNeutralAndPause_assertStopPreview() throws InterruptedException {
performClickOnDialog(BUTTON_NEUTRAL);
Thread.sleep(100);
mDialogFragment.onPause();
Thread.sleep(100);
assertThat(getLastCapturedIntent().getAction())
.isEqualTo(ACTION_FLASH_NOTIFICATION_STOP_PREVIEW);
}
@Test
public void clickNeutralAndClickNegative_assertStopPreview() throws InterruptedException {
performClickOnDialog(BUTTON_NEUTRAL);
Thread.sleep(100);
performClickOnDialog(BUTTON_NEGATIVE);
Thread.sleep(100);
assertThat(getLastCapturedIntent().getAction())
.isEqualTo(ACTION_FLASH_NOTIFICATION_STOP_PREVIEW);
}
@Test
public void clickNeutralAndClickPositive_assertStopPreview() throws InterruptedException {
performClickOnDialog(BUTTON_NEUTRAL);
Thread.sleep(100);
performClickOnDialog(BUTTON_POSITIVE);
Thread.sleep(100);
assertThat(getLastCapturedIntent().getAction())
.isEqualTo(ACTION_FLASH_NOTIFICATION_STOP_PREVIEW);
}
@Test
public void clickNeutralAndClickColor_assertStartPreview() throws InterruptedException {
performClickOnDialog(BUTTON_NEUTRAL);
Thread.sleep(100);
checkColorButton(CYAN);
Thread.sleep(500);
Intent captured = getLastCapturedIntent();
assertThat(captured.getAction()).isEqualTo(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
assertThat(captured.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE, TYPE_SHORT_PREVIEW))
.isEqualTo(TYPE_LONG_PREVIEW);
assertThat(captured.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR, Color.TRANSPARENT))
.isEqualTo(CYAN.mColorInt);
}
@Test
public void clickColorAndClickNegative_assertColor() {
checkColorButton(AZURE);
performClickOnDialog(BUTTON_NEGATIVE);
assertThat(mCurrentColor).isEqualTo(ROSE.mColorInt);
}
@Test
public void clickColorAndClickPositive_assertColor() {
checkColorButton(BLUE);
performClickOnDialog(BUTTON_POSITIVE);
assertThat(mCurrentColor).isEqualTo(BLUE.mColorInt);
}
private void checkColorButton(ScreenFlashNotificationColor color) {
mColorSelectorLayout.setCheckedColor(color.mColorInt);
}
private void performClickOnDialog(int whichButton) {
mAlertDialog.getButton(whichButton).performClick();
}
private Intent getLastCapturedIntent() {
final List<Intent> capturedIntents = new ArrayList<>(
mShadowContextWrapper.getBroadcastIntents());
final int size = capturedIntents.size();
return capturedIntents.get(size - 1);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 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 org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(ParameterizedRobolectricTestRunner.class)
public class ScreenFlashNotificationColorTest {
private static final int OPAQUE_COLOR_MASK = 0xFF000000;
@ParameterizedRobolectricTestRunner.Parameters(name = "Color: {0}")
public static List<?> params() {
final List<Object[]> list = new ArrayList<>();
for (ScreenFlashNotificationColor color : ScreenFlashNotificationColor.values()) {
list.add(new Object[]{color});
}
return list;
}
final ScreenFlashNotificationColor mColor;
public ScreenFlashNotificationColorTest(ScreenFlashNotificationColor color) {
mColor = color;
}
@Test
public void colorInt_assertNotTranslucent() {
assertThat(mColor.mColorInt & OPAQUE_COLOR_MASK).isNotEqualTo(0);
}
@Test
public void opaqueColorMask() {
assertThat(mColor.mOpaqueColorInt & OPAQUE_COLOR_MASK).isEqualTo(OPAQUE_COLOR_MASK);
}
@Test
public void stringRes_assertValid() {
assertThat(mColor.mStringRes).isNotEqualTo(0);
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2023 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.android.settings.accessibility.FlashNotificationsUtil.DEFAULT_SCREEN_FLASH_COLOR;
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Color;
import android.provider.Settings;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
import java.util.function.Consumer;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ScreenFlashNotificationPreferenceControllerTest
.ShadowScreenFlashNotificationColorDialogFragment.class,
ShadowFlashNotificationsUtils.class,
})
public class ScreenFlashNotificationPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
private static final String COLOR_DESCRIPTION_TEXT = "Colorful";
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mPreferenceScreen;
@Mock
private Preference mPreference;
@Mock
private Fragment mParentFragment;
@Mock
private FragmentManager mFragmentManager;
@Mock
private ScreenFlashNotificationColorDialogFragment mDialogFragment;
private ScreenFlashNotificationPreferenceController mController;
private ContentResolver mContentResolver;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FragmentActivity fragmentActivity = Robolectric.setupActivity(FragmentActivity.class);
Context context = fragmentActivity.getApplicationContext();
ShadowScreenFlashNotificationColorDialogFragment.setInstance(mDialogFragment);
ShadowFlashNotificationsUtils.setColorDescriptionText(COLOR_DESCRIPTION_TEXT);
mContentResolver = context.getContentResolver();
mController = new ScreenFlashNotificationPreferenceController(context, PREFERENCE_KEY);
when(mPreferenceScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
mController.setParentFragment(mParentFragment);
when(mParentFragment.getParentFragmentManager()).thenReturn(mFragmentManager);
}
@After
public void tearDown() {
ShadowScreenFlashNotificationColorDialogFragment.reset();
}
@Test
public void getAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void isChecked_setOff_assertFalse() {
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_setOn_assertTrue() {
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 1);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_whenTransparentColor_setTrue_assertNotTransparentColor() {
Settings.System.putInt(mContentResolver,
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, Color.TRANSPARENT);
mController.setChecked(true);
assertThat(Settings.System.getInt(mContentResolver,
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, 0))
.isEqualTo(DEFAULT_SCREEN_FLASH_COLOR);
}
@Test
public void setChecked_whenNotTransparent_setTrue_assertSameColor() {
Settings.System.putInt(mContentResolver,
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, 0x4D0000FF);
mController.setChecked(true);
assertThat(Settings.System.getInt(mContentResolver,
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, 0))
.isEqualTo(0x4D0000FF);
}
@Test
public void setChecked_setTrue_assertOn() {
mController.setChecked(true);
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION,
0)).isEqualTo(1);
}
@Test
public void setChecked_setFalse_assertOff() {
mController.setChecked(false);
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION,
1)).isEqualTo(0);
}
@Test
public void getSliceHighlightMenuRes() {
assertThat(mController.getSliceHighlightMenuRes())
.isEqualTo(R.string.menu_key_accessibility);
}
@Test
public void getSummary() {
assertThat(mController.getSummary()).isEqualTo(COLOR_DESCRIPTION_TEXT);
}
@Test
public void displayPreference() {
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setSummary(COLOR_DESCRIPTION_TEXT);
}
@Test
public void handlePreferenceTreeClick() {
mController.handlePreferenceTreeClick(mPreference);
verify(mDialogFragment).show(any(FragmentManager.class), anyString());
}
/**
* Note: Actually, shadow of ScreenFlashNotificationColorDialogFragment will not be used.
* Instance that returned with {@link #getInstance} should be set with {@link #setInstance}
*/
@Implements(ScreenFlashNotificationColorDialogFragment.class)
public static class ShadowScreenFlashNotificationColorDialogFragment {
static ScreenFlashNotificationColorDialogFragment sInstance = null;
@Implementation
protected static ScreenFlashNotificationColorDialogFragment getInstance(
int initialColor, Consumer<Integer> colorConsumer) {
return sInstance;
}
public static void setInstance(ScreenFlashNotificationColorDialogFragment instance) {
sInstance = instance;
}
@Resetter
public static void reset() {
sInstance = null;
}
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2023 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.android.settings.accessibility.FlashNotificationsUtil.State;
import android.content.Context;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
@Implements(FlashNotificationsUtil.class)
public class ShadowFlashNotificationsUtils {
private static boolean sIsTorchAvailable;
private static int sState;
private static String sColorDescriptionText = "";
public static void setIsTorchAvailable(boolean isTorchAvailable) {
sIsTorchAvailable = isTorchAvailable;
}
@Implementation
protected static boolean isTorchAvailable(Context context) {
return sIsTorchAvailable;
}
public static void setFlashNotificationsState(@State int state) {
sState = state;
}
@State
@Implementation
protected static int getFlashNotificationsState(Context context) {
return sState;
}
public static void setColorDescriptionText(@NonNull String text) {
sColorDescriptionText = text;
}
@Implementation
@NonNull
protected static String getColorDescriptionText(@NonNull Context context, @ColorInt int color) {
return sColorDescriptionText;
}
@Resetter
public static void reset() {
sIsTorchAvailable = false;
sState = 0;
sColorDescriptionText = "";
}
}