1 /*
2  * Copyright (C) 2021 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.keyguard;
18 
19 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
20 
21 import static com.android.systemui.flags.Flags.ENABLE_CLOCK_KEYGUARD_PRESENTATION;
22 
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 
32 import android.hardware.display.DisplayManagerGlobal;
33 import android.testing.AndroidTestingRunner;
34 import android.testing.TestableLooper;
35 import android.view.Display;
36 import android.view.DisplayInfo;
37 
38 import androidx.test.filters.SmallTest;
39 
40 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
41 import com.android.systemui.SysuiTestCase;
42 import com.android.systemui.flags.FakeFeatureFlags;
43 import com.android.systemui.navigationbar.NavigationBarController;
44 import com.android.systemui.settings.FakeDisplayTracker;
45 import com.android.systemui.statusbar.policy.KeyguardStateController;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.Mock;
51 import org.mockito.MockitoAnnotations;
52 
53 import java.util.concurrent.Executor;
54 
55 @SmallTest
56 @RunWith(AndroidTestingRunner.class)
57 @TestableLooper.RunWithLooper
58 public class KeyguardDisplayManagerTest extends SysuiTestCase {
59 
60     @Mock
61     private NavigationBarController mNavigationBarController;
62     @Mock
63     private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
64     @Mock
65     private ConnectedDisplayKeyguardPresentation.Factory
66             mConnectedDisplayKeyguardPresentationFactory;
67     @Mock
68     private KeyguardDisplayManager.KeyguardPresentation mKeyguardPresentation;
69     @Mock
70     private ConnectedDisplayKeyguardPresentation mConnectedDisplayKeyguardPresentation;
71     @Mock
72     private KeyguardDisplayManager.DeviceStateHelper mDeviceStateHelper;
73     @Mock
74     private KeyguardStateController mKeyguardStateController;
75 
76     private Executor mMainExecutor = Runnable::run;
77     private Executor mBackgroundExecutor = Runnable::run;
78     private KeyguardDisplayManager mManager;
79     private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
80     private FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
81     // The default and secondary displays are both in the default group
82     private Display mDefaultDisplay;
83     private Display mSecondaryDisplay;
84 
85     // This display is in a different group from the default and secondary displays.
86     private Display mAlwaysUnlockedDisplay;
87 
88     @Before
setUp()89     public void setUp() {
90         MockitoAnnotations.initMocks(this);
91         mFakeFeatureFlags.set(ENABLE_CLOCK_KEYGUARD_PRESENTATION, false);
92         mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController,
93                 mKeyguardStatusViewComponentFactory, mDisplayTracker, mMainExecutor,
94                 mBackgroundExecutor, mDeviceStateHelper, mKeyguardStateController,
95                 mConnectedDisplayKeyguardPresentationFactory, mFakeFeatureFlags));
96         doReturn(mKeyguardPresentation).when(mManager).createPresentation(any());
97         doReturn(mConnectedDisplayKeyguardPresentation).when(
98                 mConnectedDisplayKeyguardPresentationFactory).create(any());
99 
100         mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
101                 new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
102         mSecondaryDisplay = new Display(DisplayManagerGlobal.getInstance(),
103                 Display.DEFAULT_DISPLAY + 1,
104                 new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
105 
106         DisplayInfo alwaysUnlockedDisplayInfo = new DisplayInfo();
107         alwaysUnlockedDisplayInfo.displayId = Display.DEFAULT_DISPLAY + 2;
108         alwaysUnlockedDisplayInfo.flags = Display.FLAG_ALWAYS_UNLOCKED;
109         mAlwaysUnlockedDisplay = new Display(DisplayManagerGlobal.getInstance(),
110                 Display.DEFAULT_DISPLAY,
111                 alwaysUnlockedDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
112     }
113 
114     @Test
testShow_defaultDisplayOnly()115     public void testShow_defaultDisplayOnly() {
116         mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay});
117         mManager.show();
118         verify(mManager, never()).createPresentation(any());
119     }
120 
121     @Test
testShow_includeSecondaryDisplay()122     public void testShow_includeSecondaryDisplay() {
123         mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay});
124         mManager.show();
125         verify(mManager, times(1)).createPresentation(eq(mSecondaryDisplay));
126     }
127 
128     @Test
testShow_includeAlwaysUnlockedDisplay()129     public void testShow_includeAlwaysUnlockedDisplay() {
130         mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mAlwaysUnlockedDisplay});
131 
132         mManager.show();
133         verify(mManager, never()).createPresentation(any());
134     }
135 
136     @Test
testShow_includeSecondaryAndAlwaysUnlockedDisplays()137     public void testShow_includeSecondaryAndAlwaysUnlockedDisplays() {
138         mDisplayTracker.setAllDisplays(
139                 new Display[]{mDefaultDisplay, mSecondaryDisplay, mAlwaysUnlockedDisplay});
140 
141         mManager.show();
142         verify(mManager, times(1)).createPresentation(eq(mSecondaryDisplay));
143     }
144 
145     @Test
testShow_concurrentDisplayActive_occluded()146     public void testShow_concurrentDisplayActive_occluded() {
147         mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay});
148 
149         when(mDeviceStateHelper.isConcurrentDisplayActive(mSecondaryDisplay)).thenReturn(true);
150         when(mKeyguardStateController.isOccluded()).thenReturn(true);
151         verify(mManager, never()).createPresentation(eq(mSecondaryDisplay));
152     }
153 
154     @Test
testShow_withClockPresentationFlagEnabled_presentationCreated()155     public void testShow_withClockPresentationFlagEnabled_presentationCreated() {
156         when(mManager.createPresentation(any())).thenCallRealMethod();
157         mFakeFeatureFlags.set(ENABLE_CLOCK_KEYGUARD_PRESENTATION, true);
158         mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay});
159 
160         mManager.show();
161 
162         verify(mConnectedDisplayKeyguardPresentationFactory).create(eq(mSecondaryDisplay));
163     }
164 }
165