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.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.Mockito.doReturn;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.Mockito.when;
30 
31 import android.content.res.Configuration;
32 import android.os.Build;
33 import android.view.Window;
34 import android.view.WindowManager;
35 
36 import androidx.fragment.app.FragmentManager;
37 
38 import com.android.settings.R;
39 import com.android.settings.testutils.FakeFeatureFactory;
40 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
41 
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.Mock;
47 import org.mockito.MockitoAnnotations;
48 import org.robolectric.Robolectric;
49 import org.robolectric.RobolectricTestRunner;
50 import org.robolectric.android.controller.ActivityController;
51 import org.robolectric.util.ReflectionHelpers;
52 
53 @RunWith(RobolectricTestRunner.class)
54 public class SettingsPanelActivityTest {
55 
56     private FakeFeatureFactory mFakeFeatureFactory;
57     private FakeSettingsPanelActivity mSettingsPanelActivity;
58     private PanelFeatureProvider mPanelFeatureProvider;
59     private FakePanelContent mFakePanelContent;
60     @Mock
61     private PanelFragment mPanelFragment;
62     @Mock
63     private FragmentManager mFragmentManager;
64 
65     @Before
setUp()66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
69         mSettingsPanelActivity = spy(
70                 Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get());
71         mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
72         mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
73         mFakePanelContent = new FakePanelContent();
74         doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any());
75 
76         mSettingsPanelActivity.mPanelFragment = mPanelFragment;
77         when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment);
78         when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
79     }
80 
81     @Test
onStart_isNotDebuggable_shouldHideSystemOverlay()82     public void onStart_isNotDebuggable_shouldHideSystemOverlay() {
83         ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
84 
85         final ActivityController<SettingsPanelActivity> activityController =
86                 Robolectric.buildActivity(SettingsPanelActivity.class).create();
87         final SettingsPanelActivity activity = spy(activityController.get());
88         final Window window = mock(Window.class);
89         when(activity.getWindow()).thenReturn(window);
90         activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
91 
92         activityController.start();
93 
94         verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
95     }
96 
97     @Test
onStop_isNotDebuggable_shouldRemoveHideSystemOverlay()98     public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() {
99         ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
100 
101         final ActivityController<SettingsPanelActivity> activityController =
102                 Robolectric.buildActivity(SettingsPanelActivity.class).create();
103         final SettingsPanelActivity activity = spy(activityController.get());
104         final Window window = mock(Window.class);
105         when(activity.getWindow()).thenReturn(window);
106         activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
107 
108         activityController.start();
109 
110         verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
111 
112         final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
113         when(window.getAttributes()).thenReturn(layoutParams);
114 
115         activityController.stop();
116         final ArgumentCaptor<WindowManager.LayoutParams> paramCaptor = ArgumentCaptor.forClass(
117                 WindowManager.LayoutParams.class);
118 
119         verify(window).setAttributes(paramCaptor.capture());
120         assertThat(paramCaptor.getValue().privateFlags
121                 & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
122     }
123 
124     @Test
onStop_panelIsNotCreating_shouldForceUpdate()125     public void onStop_panelIsNotCreating_shouldForceUpdate() {
126         mSettingsPanelActivity.mForceCreation = false;
127         when(mPanelFragment.isPanelCreating()).thenReturn(false);
128         mSettingsPanelActivity.mPanelFragment = mPanelFragment;
129 
130         mSettingsPanelActivity.onStop();
131 
132         assertThat(mSettingsPanelActivity.mForceCreation).isTrue();
133     }
134 
135     @Test
onStop_panelIsCreating_shouldNotForceUpdate()136     public void onStop_panelIsCreating_shouldNotForceUpdate() {
137         mSettingsPanelActivity.mForceCreation = false;
138         when(mPanelFragment.isPanelCreating()).thenReturn(true);
139         mSettingsPanelActivity.mPanelFragment = mPanelFragment;
140 
141         mSettingsPanelActivity.onStop();
142 
143         assertThat(mSettingsPanelActivity.mForceCreation).isFalse();
144     }
145 
146     @Test
onConfigurationChanged_shouldForceUpdate()147     public void onConfigurationChanged_shouldForceUpdate() {
148         mSettingsPanelActivity.mForceCreation = false;
149 
150         mSettingsPanelActivity.onConfigurationChanged(new Configuration());
151 
152         assertThat(mSettingsPanelActivity.mForceCreation).isTrue();
153     }
154 
155     @Test
onNewIntent_panelIsNotCreating_shouldUpdatePanel()156     public void onNewIntent_panelIsNotCreating_shouldUpdatePanel() {
157         when(mPanelFragment.isPanelCreating()).thenReturn(false);
158 
159         mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent());
160 
161         verify(mPanelFragment).updatePanelWithAnimation();
162     }
163 
164     @Test
onNewIntent_panelIsCreating_shouldNotUpdatePanel()165     public void onNewIntent_panelIsCreating_shouldNotUpdatePanel() {
166         when(mPanelFragment.isPanelCreating()).thenReturn(true);
167 
168         mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent());
169 
170         verify(mPanelFragment, never()).updatePanelWithAnimation();
171     }
172 
173     @Test
onNewIntent_panelIsShowingTheSameAction_shouldNotUpdatePanel()174     public void onNewIntent_panelIsShowingTheSameAction_shouldNotUpdatePanel() {
175         when(mPanelFragment.isPanelCreating()).thenReturn(false);
176         when(mPanelFragment.getArguments()).thenReturn(mSettingsPanelActivity.mBundle);
177 
178         mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent());
179 
180         verify(mPanelFragment, never()).updatePanelWithAnimation();
181     }
182 }
183