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.panel; 18 19 import static android.content.res.Configuration.UI_MODE_NIGHT_NO; 20 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyInt; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.spy; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.content.res.Configuration; 34 import android.os.Build; 35 import android.view.View; 36 import android.view.Window; 37 import android.view.WindowManager; 38 39 import androidx.core.view.ViewCompat; 40 import androidx.core.view.WindowInsetsControllerCompat; 41 import androidx.fragment.app.FragmentManager; 42 import androidx.fragment.app.FragmentTransaction; 43 44 import com.android.settings.R; 45 import com.android.settings.testutils.FakeFeatureFactory; 46 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; 47 48 import org.junit.After; 49 import org.junit.Before; 50 import org.junit.Ignore; 51 import org.junit.Test; 52 import org.junit.runner.RunWith; 53 import org.mockito.ArgumentCaptor; 54 import org.mockito.Mock; 55 import org.mockito.MockitoAnnotations; 56 import org.robolectric.Robolectric; 57 import org.robolectric.RobolectricTestRunner; 58 import org.robolectric.android.controller.ActivityController; 59 import org.robolectric.annotation.Config; 60 import org.robolectric.util.ReflectionHelpers; 61 62 @Deprecated(forRemoval = true) 63 @RunWith(RobolectricTestRunner.class) 64 @Config(shadows = { 65 com.android.settings.testutils.shadow.ShadowFragment.class, 66 }) 67 public class SettingsPanelActivityTest { 68 69 private FakeFeatureFactory mFakeFeatureFactory; 70 private FakeSettingsPanelActivity mSettingsPanelActivity; 71 private PanelFeatureProvider mPanelFeatureProvider; 72 private FakePanelContent mFakePanelContent; 73 @Mock 74 private PanelFragment mPanelFragment; 75 @Mock 76 private FragmentManager mFragmentManager; 77 @Mock 78 private FragmentTransaction mTransaction; 79 private int mOriginalUiMode; 80 81 @Before setUp()82 public void setUp() { 83 MockitoAnnotations.initMocks(this); 84 mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); 85 mSettingsPanelActivity = spy( 86 Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get()); 87 mPanelFeatureProvider = spy(new PanelFeatureProviderImpl()); 88 mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider; 89 mFakePanelContent = new FakePanelContent(); 90 doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any()); 91 92 mSettingsPanelActivity.mPanelFragment = mPanelFragment; 93 when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment); 94 when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager); 95 mOriginalUiMode = mSettingsPanelActivity.getResources().getConfiguration().uiMode; 96 when(mFragmentManager.beginTransaction()).thenReturn(mTransaction); 97 when(mTransaction.add(anyInt(), any())).thenReturn(mTransaction); 98 when(mTransaction.commit()).thenReturn(0); // don't care about return value 99 } 100 101 @After tearDown()102 public void tearDown() { 103 mSettingsPanelActivity.getResources().getConfiguration().uiMode = mOriginalUiMode; 104 } 105 106 @Ignore("b/313576125") 107 @Test onStart_isNotDebuggable_shouldHideSystemOverlay()108 public void onStart_isNotDebuggable_shouldHideSystemOverlay() { 109 ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false); 110 111 final ActivityController<SettingsPanelActivity> activityController = 112 Robolectric.buildActivity(SettingsPanelActivity.class).create(); 113 final SettingsPanelActivity activity = spy(activityController.get()); 114 final Window window = mock(Window.class); 115 when(activity.getWindow()).thenReturn(window); 116 activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity)); 117 118 activityController.start(); 119 120 verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 121 } 122 123 @Ignore("b/313576125") 124 @Test onStop_isNotDebuggable_shouldRemoveHideSystemOverlay()125 public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() { 126 ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false); 127 128 final ActivityController<SettingsPanelActivity> activityController = 129 Robolectric.buildActivity(SettingsPanelActivity.class).create(); 130 final SettingsPanelActivity activity = spy(activityController.get()); 131 final Window window = mock(Window.class); 132 when(activity.getWindow()).thenReturn(window); 133 activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity)); 134 135 activityController.start(); 136 137 verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 138 139 final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); 140 when(window.getAttributes()).thenReturn(layoutParams); 141 142 activityController.stop(); 143 final ArgumentCaptor<WindowManager.LayoutParams> paramCaptor = ArgumentCaptor.forClass( 144 WindowManager.LayoutParams.class); 145 146 verify(window).setAttributes(paramCaptor.capture()); 147 assertThat(paramCaptor.getValue().privateFlags 148 & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0); 149 } 150 151 @Ignore("b/313576125") 152 @Test onStop_panelIsNotCreating_shouldForceUpdate()153 public void onStop_panelIsNotCreating_shouldForceUpdate() { 154 mSettingsPanelActivity.mForceCreation = false; 155 when(mPanelFragment.isPanelCreating()).thenReturn(false); 156 mSettingsPanelActivity.mPanelFragment = mPanelFragment; 157 158 mSettingsPanelActivity.onStop(); 159 160 assertThat(mSettingsPanelActivity.mForceCreation).isTrue(); 161 } 162 163 @Ignore("b/313576125") 164 @Test onStop_panelIsCreating_shouldNotForceUpdate()165 public void onStop_panelIsCreating_shouldNotForceUpdate() { 166 mSettingsPanelActivity.mForceCreation = false; 167 when(mPanelFragment.isPanelCreating()).thenReturn(true); 168 mSettingsPanelActivity.mPanelFragment = mPanelFragment; 169 170 mSettingsPanelActivity.onStop(); 171 172 assertThat(mSettingsPanelActivity.mForceCreation).isFalse(); 173 } 174 175 @Test onConfigurationChanged_shouldForceUpdate()176 public void onConfigurationChanged_shouldForceUpdate() { 177 mSettingsPanelActivity.mForceCreation = false; 178 179 mSettingsPanelActivity.onConfigurationChanged(new Configuration()); 180 181 assertThat(mSettingsPanelActivity.mForceCreation).isTrue(); 182 } 183 184 @Test onNewIntent_panelIsNotCreating_shouldUpdatePanel()185 public void onNewIntent_panelIsNotCreating_shouldUpdatePanel() { 186 when(mPanelFragment.isPanelCreating()).thenReturn(false); 187 188 mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); 189 190 verify(mPanelFragment).updatePanelWithAnimation(); 191 } 192 193 @Test onNewIntent_panelIsCreating_shouldNotUpdatePanel()194 public void onNewIntent_panelIsCreating_shouldNotUpdatePanel() { 195 when(mPanelFragment.isPanelCreating()).thenReturn(true); 196 197 mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); 198 199 verify(mPanelFragment, never()).updatePanelWithAnimation(); 200 } 201 202 @Test onNewIntent_panelIsShowingTheSameAction_shouldNotUpdatePanel()203 public void onNewIntent_panelIsShowingTheSameAction_shouldNotUpdatePanel() { 204 when(mPanelFragment.isPanelCreating()).thenReturn(false); 205 when(mPanelFragment.getArguments()).thenReturn(mSettingsPanelActivity.mBundle); 206 207 mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); 208 209 verify(mPanelFragment, never()).updatePanelWithAnimation(); 210 } 211 212 @Test onCreated_isWindowBottomPaddingZero()213 public void onCreated_isWindowBottomPaddingZero() { 214 int paddingBottom = mSettingsPanelActivity.getWindow().getDecorView().getPaddingBottom(); 215 assertThat(paddingBottom).isEqualTo(0); 216 } 217 218 @Test notInNightMode_lightNavigationBarAppearance()219 public void notInNightMode_lightNavigationBarAppearance() { 220 Configuration config = mSettingsPanelActivity.getResources().getConfiguration(); 221 config.uiMode = UI_MODE_NIGHT_NO; 222 mSettingsPanelActivity.onConfigurationChanged(config); // forces creation 223 224 mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); 225 verify(mFragmentManager).beginTransaction(); 226 227 View decorView = mSettingsPanelActivity.getWindow().getDecorView(); 228 WindowInsetsControllerCompat controller = ViewCompat.getWindowInsetsController(decorView); 229 assertThat(controller.isAppearanceLightNavigationBars()).isTrue(); 230 } 231 } 232