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