blob: 1e9000b76c3fb3a7f1f59d836a1aa8d4e3aa48be [file] [log] [blame]
Jason Monkd4afe152017-05-01 15:37:43 -04001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui;
16
Adrian Roos5b518852018-01-23 17:23:38 +010017import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
18
Charles Chen10ca70b2018-11-28 00:03:38 +080019import static com.android.systemui.ScreenDecorations.rectsToRegion;
Jason Monkd4afe152017-05-01 15:37:43 -040020import static com.android.systemui.tuner.TunablePadding.FLAG_END;
21import static com.android.systemui.tuner.TunablePadding.FLAG_START;
22
Adrian Roos5b518852018-01-23 17:23:38 +010023import static org.hamcrest.Matchers.is;
Adrian Roos64c9d902018-08-20 13:43:38 +020024import static org.junit.Assert.assertEquals;
Charles Chen10ca70b2018-11-28 00:03:38 +080025import static org.junit.Assert.assertThat;
Jason Monkd4afe152017-05-01 15:37:43 -040026import static org.mockito.ArgumentMatchers.any;
27import static org.mockito.ArgumentMatchers.anyInt;
28import static org.mockito.ArgumentMatchers.anyString;
29import static org.mockito.ArgumentMatchers.eq;
Jason Monkd4afe152017-05-01 15:37:43 -040030import static org.mockito.Mockito.mock;
31import static org.mockito.Mockito.never;
Lucas Dupin34f6d962019-02-22 14:47:50 -080032import static org.mockito.Mockito.reset;
Jason Monkd4afe152017-05-01 15:37:43 -040033import static org.mockito.Mockito.spy;
34import static org.mockito.Mockito.times;
35import static org.mockito.Mockito.verify;
36import static org.mockito.Mockito.when;
37
38import android.app.Fragment;
Adrian Roos5b518852018-01-23 17:23:38 +010039import android.content.res.Configuration;
Issei Suzuki43190bd2018-08-20 17:28:41 +020040import android.graphics.Rect;
Adrian Roos73ab97c2018-08-02 15:56:15 +020041import android.os.Handler;
Jason Monkd4afe152017-05-01 15:37:43 -040042import android.testing.AndroidTestingRunner;
Adrian Roos73ab97c2018-08-02 15:56:15 +020043import android.testing.TestableLooper;
Beverlye91f0d02018-05-15 14:40:47 -040044import android.testing.TestableLooper.RunWithLooper;
Jason Monkd4afe152017-05-01 15:37:43 -040045import android.view.Display;
46import android.view.View;
47import android.view.WindowManager;
48
Brett Chabot84151d92019-02-27 15:37:59 -080049import androidx.test.filters.SmallTest;
50
Jason Monkd4afe152017-05-01 15:37:43 -040051import com.android.systemui.R.dimen;
Adrian Roos5b518852018-01-23 17:23:38 +010052import com.android.systemui.ScreenDecorations.TunablePaddingTagListener;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000053import com.android.systemui.broadcast.BroadcastDispatcher;
Jason Monkd4afe152017-05-01 15:37:43 -040054import com.android.systemui.fragments.FragmentHostManager;
55import com.android.systemui.fragments.FragmentService;
56import com.android.systemui.statusbar.phone.StatusBar;
57import com.android.systemui.statusbar.phone.StatusBarWindowView;
58import com.android.systemui.tuner.TunablePadding;
59import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
60import com.android.systemui.tuner.TunerService;
61
62import org.junit.Before;
63import org.junit.Test;
64import org.junit.runner.RunWith;
Dave Mankoff4ddc25b2019-10-23 15:46:08 -040065import org.mockito.Mock;
66import org.mockito.MockitoAnnotations;
Jason Monkd4afe152017-05-01 15:37:43 -040067
Issei Suzuki43190bd2018-08-20 17:28:41 +020068import java.util.Collections;
69
Dave Mankoff4ddc25b2019-10-23 15:46:08 -040070import dagger.Lazy;
71
Beverlye91f0d02018-05-15 14:40:47 -040072@RunWithLooper
Jason Monkd4afe152017-05-01 15:37:43 -040073@RunWith(AndroidTestingRunner.class)
Jason Monkfba8faf2017-05-23 10:42:59 -040074@SmallTest
Adrian Roos5b518852018-01-23 17:23:38 +010075public class ScreenDecorationsTest extends SysuiTestCase {
Jason Monkd4afe152017-05-01 15:37:43 -040076
Adrian Roos73ab97c2018-08-02 15:56:15 +020077 private TestableLooper mTestableLooper;
Adrian Roos5b518852018-01-23 17:23:38 +010078 private ScreenDecorations mScreenDecorations;
Dave Mankoff4ddc25b2019-10-23 15:46:08 -040079 @Mock private StatusBar mStatusBar;
Jason Monkd4afe152017-05-01 15:37:43 -040080 private WindowManager mWindowManager;
81 private FragmentService mFragmentService;
82 private FragmentHostManager mFragmentHostManager;
Jason Monkd4afe152017-05-01 15:37:43 -040083 private StatusBarWindowView mView;
84 private TunablePaddingService mTunablePaddingService;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000085 private Handler mMainHandler;
86 @Mock
87 private TunerService mTunerService;
88 @Mock
89 private BroadcastDispatcher mBroadcastDispatcher;
Dave Mankoff4ddc25b2019-10-23 15:46:08 -040090 @Mock private Lazy<StatusBar> mStatusBarLazy;
Jason Monkd4afe152017-05-01 15:37:43 -040091
92 @Before
93 public void setup() {
Dave Mankoff4ddc25b2019-10-23 15:46:08 -040094 MockitoAnnotations.initMocks(this);
95
Adrian Roos73ab97c2018-08-02 15:56:15 +020096 mTestableLooper = TestableLooper.get(this);
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000097 mMainHandler = new Handler(mTestableLooper.getLooper());
Lucas Dupin34f6d962019-02-22 14:47:50 -080098 mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
Lucas Dupin34f6d962019-02-22 14:47:50 -080099 mFragmentService = mDependency.injectMockDependency(FragmentService.class);
Adrian Roos73ab97c2018-08-02 15:56:15 +0200100
Jason Monkd4afe152017-05-01 15:37:43 -0400101 mWindowManager = mock(WindowManager.class);
102 mView = spy(new StatusBarWindowView(mContext, null));
Dave Mankoff4ddc25b2019-10-23 15:46:08 -0400103 when(mStatusBarLazy.get()).thenReturn(mStatusBar);
Jason Monkd4afe152017-05-01 15:37:43 -0400104 when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
Jason Monkd4afe152017-05-01 15:37:43 -0400105
106 Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
107 when(mWindowManager.getDefaultDisplay()).thenReturn(display);
108 mContext.addMockSystemService(WindowManager.class, mWindowManager);
109
Jason Monkd4afe152017-05-01 15:37:43 -0400110 mFragmentHostManager = mock(FragmentHostManager.class);
111 when(mFragmentService.getFragmentHostManager(any())).thenReturn(mFragmentHostManager);
112
Adrian Roos73ab97c2018-08-02 15:56:15 +0200113
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000114 mScreenDecorations = new ScreenDecorations(mContext, mStatusBarLazy, mMainHandler,
115 mBroadcastDispatcher, mTunerService) {
Adrian Roos73ab97c2018-08-02 15:56:15 +0200116 @Override
117 public void start() {
118 super.start();
119 mTestableLooper.processAllMessages();
120 }
121
122 @Override
123 Handler startHandlerThread() {
124 return new Handler(mTestableLooper.getLooper());
125 }
126
127 @Override
128 protected void onConfigurationChanged(Configuration newConfig) {
129 super.onConfigurationChanged(newConfig);
130 mTestableLooper.processAllMessages();
131 }
132
133 @Override
134 public void onTuningChanged(String key, String newValue) {
135 super.onTuningChanged(key, newValue);
136 mTestableLooper.processAllMessages();
137 }
138 };
Adrian Roos5b518852018-01-23 17:23:38 +0100139 mScreenDecorations.mComponents = mContext.getComponents();
Lucas Dupin34f6d962019-02-22 14:47:50 -0800140 reset(mTunerService);
Jason Monkd4afe152017-05-01 15:37:43 -0400141 }
142
143 @Test
Adrian Roos5b518852018-01-23 17:23:38 +0100144 public void testNoRounding_NoCutout() {
145 mContext.getOrCreateTestableResources().addOverride(
146 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
Beverly4d1113d2019-01-03 14:45:10 -0500147 mContext.getOrCreateTestableResources().addOverride(
148 com.android.internal.R.dimen.rounded_corner_radius, 0);
149 mContext.getOrCreateTestableResources().addOverride(
150 com.android.internal.R.dimen.rounded_corner_radius_top, 0);
151 mContext.getOrCreateTestableResources().addOverride(
152 com.android.internal.R.dimen.rounded_corner_radius_bottom, 0);
Jason Monkc429f692017-06-27 13:13:49 -0400153 mContext.getOrCreateTestableResources()
154 .addOverride(dimen.rounded_corner_content_padding, 0);
Jason Monkd4afe152017-05-01 15:37:43 -0400155
Adrian Roos5b518852018-01-23 17:23:38 +0100156 mScreenDecorations.start();
Jason Monkd4afe152017-05-01 15:37:43 -0400157 // No views added.
158 verify(mWindowManager, never()).addView(any(), any());
159 // No Fragments watched.
160 verify(mFragmentHostManager, never()).addTagListener(any(), any());
161 // No Tuners tuned.
162 verify(mTunerService, never()).addTunable(any(), any());
163 }
164
165 @Test
166 public void testRounding() {
Adrian Roos5b518852018-01-23 17:23:38 +0100167 mContext.getOrCreateTestableResources().addOverride(
168 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
Beverly4d1113d2019-01-03 14:45:10 -0500169 mContext.getOrCreateTestableResources().addOverride(
170 com.android.internal.R.dimen.rounded_corner_radius, 20);
Jason Monkc429f692017-06-27 13:13:49 -0400171 mContext.getOrCreateTestableResources()
172 .addOverride(dimen.rounded_corner_content_padding, 20);
Jason Monkd4afe152017-05-01 15:37:43 -0400173
Adrian Roos5b518852018-01-23 17:23:38 +0100174 mScreenDecorations.start();
Jason Monkd4afe152017-05-01 15:37:43 -0400175 // Add 2 windows for rounded corners (top and bottom).
176 verify(mWindowManager, times(2)).addView(any(), any());
177
Jason Monk089981b2017-06-30 09:10:01 -0400178 // Add 2 tag listeners for each of the fragments that are needed.
179 verify(mFragmentHostManager, times(2)).addTagListener(any(), any());
Jason Monkd4afe152017-05-01 15:37:43 -0400180 // One tunable.
181 verify(mTunerService, times(1)).addTunable(any(), any());
182 // One TunablePadding.
183 verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt());
184 }
185
186 @Test
Adrian Roos5b518852018-01-23 17:23:38 +0100187 public void testCutout() {
188 mContext.getOrCreateTestableResources().addOverride(
189 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, true);
Beverly4d1113d2019-01-03 14:45:10 -0500190 mContext.getOrCreateTestableResources().addOverride(
191 com.android.internal.R.dimen.rounded_corner_radius, 0);
Adrian Roos5b518852018-01-23 17:23:38 +0100192 mContext.getOrCreateTestableResources()
193 .addOverride(dimen.rounded_corner_content_padding, 0);
194
195 mScreenDecorations.start();
196 // Add 2 windows for rounded corners (top and bottom).
197 verify(mWindowManager, times(2)).addView(any(), any());
198 }
199
200 @Test
201 public void testDelayedCutout() {
202 mContext.getOrCreateTestableResources().addOverride(
203 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
Beverly4d1113d2019-01-03 14:45:10 -0500204 mContext.getOrCreateTestableResources().addOverride(
205 com.android.internal.R.dimen.rounded_corner_radius, 0);
Adrian Roos5b518852018-01-23 17:23:38 +0100206 mContext.getOrCreateTestableResources()
207 .addOverride(dimen.rounded_corner_content_padding, 0);
208
209 mScreenDecorations.start();
210
211 mContext.getOrCreateTestableResources().addOverride(
212 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, true);
213 mScreenDecorations.onConfigurationChanged(new Configuration());
214
215 // Add 2 windows for rounded corners (top and bottom).
216 verify(mWindowManager, times(2)).addView(any(), any());
217 }
218
219 @Test
220 public void hasRoundedCornerOverlayFlagSet() {
221 assertThat(mScreenDecorations.getWindowLayoutParams().privateFlags
222 & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
223 is(PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY));
224 }
225
226 @Test
Jason Monkd4afe152017-05-01 15:37:43 -0400227 public void testPaddingTagListener() {
228 TunablePaddingTagListener tagListener = new TunablePaddingTagListener(14, 5);
229 View v = mock(View.class);
230 View child = mock(View.class);
231 Fragment f = mock(Fragment.class);
232 TunablePadding padding = mock(TunablePadding.class);
233
234 when(mTunablePaddingService.add(any(), anyString(), anyInt(), anyInt()))
235 .thenReturn(padding);
236 when(f.getView()).thenReturn(v);
237 when(v.findViewById(5)).thenReturn(child);
238
239 // Trigger callback and verify we get a TunablePadding created.
240 tagListener.onFragmentViewCreated(null, f);
Adrian Roos5b518852018-01-23 17:23:38 +0100241 verify(mTunablePaddingService).add(eq(child), eq(ScreenDecorations.PADDING), eq(14),
Jason Monkd4afe152017-05-01 15:37:43 -0400242 eq(FLAG_START | FLAG_END));
243
244 // Call again and verify destroy is called.
245 tagListener.onFragmentViewCreated(null, f);
246 verify(padding).destroy();
247 }
248
Adrian Roos64c9d902018-08-20 13:43:38 +0200249 @Test
250 public void testUpdateRoundedCorners() {
251 mContext.getOrCreateTestableResources().addOverride(
252 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
Beverly4d1113d2019-01-03 14:45:10 -0500253 mContext.getOrCreateTestableResources().addOverride(
254 com.android.internal.R.dimen.rounded_corner_radius, 20);
Adrian Roos64c9d902018-08-20 13:43:38 +0200255
256 mScreenDecorations.start();
257 assertEquals(mScreenDecorations.mRoundedDefault, 20);
258
Beverly4d1113d2019-01-03 14:45:10 -0500259 mContext.getOrCreateTestableResources().addOverride(
260 com.android.internal.R.dimen.rounded_corner_radius, 5);
Adrian Roos64c9d902018-08-20 13:43:38 +0200261 mScreenDecorations.onConfigurationChanged(null);
262 assertEquals(mScreenDecorations.mRoundedDefault, 5);
263 }
Issei Suzuki43190bd2018-08-20 17:28:41 +0200264
265 @Test
266 public void testBoundingRectsToRegion() throws Exception {
267 Rect rect = new Rect(1, 2, 3, 4);
268 assertThat(rectsToRegion(Collections.singletonList(rect)).getBounds(), is(rect));
269 }
270
Geoffrey Pitsch0053e992017-05-22 15:32:29 -0400271}