1 /* 2 * Copyright (C) 2019 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.homepage.contextualcards.slices; 18 19 import static android.content.res.Configuration.UI_MODE_NIGHT_NO; 20 import static android.content.res.Configuration.UI_MODE_NIGHT_YES; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.Mockito.doReturn; 25 import static org.mockito.Mockito.spy; 26 import static org.mockito.Mockito.when; 27 28 import android.app.UiModeManager; 29 import android.content.Context; 30 import android.net.Uri; 31 import android.os.BatteryManager; 32 import android.os.PowerManager; 33 34 import androidx.slice.Slice; 35 import androidx.slice.SliceMetadata; 36 import androidx.slice.SliceProvider; 37 import androidx.slice.widget.SliceLiveData; 38 39 import com.android.settings.R; 40 import com.android.settings.slices.CustomSliceRegistry; 41 import com.android.settings.slices.SlicesFeatureProviderImpl; 42 import com.android.settings.testutils.FakeFeatureFactory; 43 44 import org.junit.Before; 45 import org.junit.Ignore; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.mockito.Mock; 49 import org.mockito.MockitoAnnotations; 50 import org.robolectric.RobolectricTestRunner; 51 import org.robolectric.RuntimeEnvironment; 52 import org.robolectric.annotation.Config; 53 54 @RunWith(RobolectricTestRunner.class) 55 @Config(shadows = { 56 com.android.settings.testutils.shadow.ShadowDrawable.class, 57 }) 58 public class DarkThemeSliceTest { 59 @Mock 60 private BatteryManager mBatteryManager; 61 @Mock 62 private PowerManager mPowerManager; 63 @Mock 64 private UiModeManager mUiModeManager; 65 66 private Context mContext; 67 private DarkThemeSlice mDarkThemeSlice; 68 private FakeFeatureFactory mFeatureFactory; 69 70 @Before setUp()71 public void setUp() { 72 MockitoAnnotations.initMocks(this); 73 mContext = spy(RuntimeEnvironment.application); 74 mFeatureFactory = FakeFeatureFactory.setupForTest(); 75 mFeatureFactory.slicesFeatureProvider = new SlicesFeatureProviderImpl(); 76 mFeatureFactory.slicesFeatureProvider.newUiSession(); 77 doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); 78 when(mPowerManager.isPowerSaveMode()).thenReturn(false); 79 doReturn(mUiModeManager).when(mContext).getSystemService(UiModeManager.class); 80 81 // Set-up specs for SliceMetadata. 82 SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); 83 mDarkThemeSlice = new DarkThemeSlice(mContext); 84 mDarkThemeSlice.sKeepSliceShow = false; 85 } 86 87 @Test getUri_shouldBeDarkThemeSliceUri()88 public void getUri_shouldBeDarkThemeSliceUri() { 89 final Uri uri = mDarkThemeSlice.getUri(); 90 91 assertThat(uri).isEqualTo(CustomSliceRegistry.DARK_THEME_SLICE_URI); 92 } 93 94 @Test isAvailable_inDarkThemeMode_returnFalse()95 public void isAvailable_inDarkThemeMode_returnFalse() { 96 mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_YES; 97 98 assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse(); 99 } 100 101 @Test isAvailable_nonDarkTheme_autoNightMode_returnFalse()102 public void isAvailable_nonDarkTheme_autoNightMode_returnFalse() { 103 mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_NO; 104 setNightMode(UiModeManager.MODE_NIGHT_AUTO); 105 106 assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse(); 107 } 108 109 @Test isAvailable_nonDarkTheme_customNightMode_returnFalse()110 public void isAvailable_nonDarkTheme_customNightMode_returnFalse() { 111 mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_NO; 112 setNightMode(UiModeManager.MODE_NIGHT_CUSTOM); 113 114 assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse(); 115 } 116 117 @Test isAvailable_nonDarkThemeBatteryCapacityEq100_returnFalse()118 public void isAvailable_nonDarkThemeBatteryCapacityEq100_returnFalse() { 119 setBatteryCapacityLevel(100); 120 setNightMode(UiModeManager.MODE_NIGHT_NO); 121 122 assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse(); 123 } 124 125 @Test isAvailable_nonDarkThemeBatteryCapacityLt50_returnTrue()126 public void isAvailable_nonDarkThemeBatteryCapacityLt50_returnTrue() { 127 setBatteryCapacityLevel(40); 128 setNightMode(UiModeManager.MODE_NIGHT_NO); 129 130 assertThat(mDarkThemeSlice.isAvailable(mContext)).isTrue(); 131 } 132 133 @Ignore("b/313598030") 134 @Test getSlice_batterySaver_returnErrorSlice()135 public void getSlice_batterySaver_returnErrorSlice() { 136 when(mPowerManager.isPowerSaveMode()).thenReturn(true); 137 138 final Slice mediaSlice = mDarkThemeSlice.getSlice(); 139 final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); 140 assertThat(metadata.isErrorSlice()).isTrue(); 141 } 142 143 @Ignore("b/313598030") 144 @Test getSlice_notAvailable_returnErrorSlice()145 public void getSlice_notAvailable_returnErrorSlice() { 146 mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_YES; 147 148 final Slice mediaSlice = mDarkThemeSlice.getSlice(); 149 final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); 150 assertThat(metadata.isErrorSlice()).isTrue(); 151 } 152 153 @Ignore("b/313598030") 154 @Test getSlice_newSession_notAvailable_returnErrorSlice()155 public void getSlice_newSession_notAvailable_returnErrorSlice() { 156 // previous displayed: yes 157 mDarkThemeSlice.sKeepSliceShow = true; 158 // Session: use original value + 1 to become a new session 159 mDarkThemeSlice.sActiveUiSession = 160 mFeatureFactory.slicesFeatureProvider.getUiSessionToken() + 1; 161 162 mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_YES; 163 164 final Slice mediaSlice = mDarkThemeSlice.getSlice(); 165 final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); 166 assertThat(metadata.isErrorSlice()).isTrue(); 167 } 168 169 @Test getSlice_previouslyDisplayed_isAvailable_returnSlice()170 public void getSlice_previouslyDisplayed_isAvailable_returnSlice() { 171 mDarkThemeSlice.sActiveUiSession = 172 mFeatureFactory.slicesFeatureProvider.getUiSessionToken(); 173 mDarkThemeSlice.sKeepSliceShow = true; 174 setBatteryCapacityLevel(40); 175 setNightMode(UiModeManager.MODE_NIGHT_NO); 176 177 assertThat(mDarkThemeSlice.getSlice()).isNotNull(); 178 } 179 180 @Ignore("b/313598030") 181 @Test getSlice_sliceNotClicked_notAvailable_returnErrorSlice()182 public void getSlice_sliceNotClicked_notAvailable_returnErrorSlice() { 183 mDarkThemeSlice.sSliceClicked = false; 184 185 mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_YES; 186 187 final Slice mediaSlice = mDarkThemeSlice.getSlice(); 188 final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); 189 assertThat(metadata.isErrorSlice()).isTrue(); 190 } 191 192 @Test getSlice_sliceClicked_isAvailable_returnSlice()193 public void getSlice_sliceClicked_isAvailable_returnSlice() { 194 mDarkThemeSlice.sSliceClicked = true; 195 196 setBatteryCapacityLevel(40); 197 setNightMode(UiModeManager.MODE_NIGHT_NO); 198 199 assertThat(mDarkThemeSlice.getSlice()).isNotNull(); 200 } 201 202 @Test getSlice_isAvailable_returnSlice()203 public void getSlice_isAvailable_returnSlice() { 204 setBatteryCapacityLevel(40); 205 setNightMode(UiModeManager.MODE_NIGHT_NO); 206 207 assertThat(mDarkThemeSlice.getSlice()).isNotNull(); 208 } 209 210 @Test getSlice_isAvailable_showTitleSubtitle()211 public void getSlice_isAvailable_showTitleSubtitle() { 212 setBatteryCapacityLevel(40); 213 setNightMode(UiModeManager.MODE_NIGHT_NO); 214 215 final Slice slice = mDarkThemeSlice.getSlice(); 216 final SliceMetadata metadata = SliceMetadata.from(mContext, slice); 217 assertThat(metadata.getTitle()).isEqualTo( 218 mContext.getString(R.string.dark_theme_slice_title)); 219 assertThat(metadata.getSubtitle()).isEqualTo( 220 mContext.getString(R.string.dark_theme_slice_subtitle)); 221 } 222 setBatteryCapacityLevel(int power_level)223 private void setBatteryCapacityLevel(int power_level) { 224 mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_NO; 225 doReturn(mBatteryManager).when(mContext).getSystemService(BatteryManager.class); 226 when(mBatteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)) 227 .thenReturn(power_level); 228 } 229 setNightMode(int mode)230 private void setNightMode(int mode) { 231 when(mUiModeManager.getNightMode()).thenReturn(mode); 232 } 233 } 234