1 /*
2  * Copyright (C) 2020 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.systemui.navigationbar;
18 
19 import static org.mockito.Mockito.doReturn;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.spy;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify;
24 
25 import android.view.Display;
26 import android.view.View;
27 import android.view.WindowInsetsController;
28 
29 import androidx.test.InstrumentationRegistry;
30 import androidx.test.filters.SmallTest;
31 import androidx.test.runner.AndroidJUnit4;
32 
33 import com.android.systemui.SysuiTestCase;
34 import com.android.systemui.SysuiTestableContext;
35 import com.android.systemui.shared.rotation.RotationButton;
36 import com.android.systemui.shared.rotation.RotationButtonController;
37 import com.android.systemui.statusbar.policy.RotationLockController;
38 
39 import org.junit.Before;
40 import org.junit.Rule;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.MockitoAnnotations;
44 
45 import java.util.function.Supplier;
46 
47 /** atest NavigationBarRotationContextTest */
48 @SmallTest
49 @RunWith(AndroidJUnit4.class)
50 public class NavigationBarRotationContextTest extends SysuiTestCase {
51     static final int DEFAULT_ROTATE = 0;
52 
53     @Rule
54     public final SysuiTestableContext mContext = new SysuiTestableContext(
55             InstrumentationRegistry.getContext(), getLeakCheck());
56     private RotationButtonController mRotationButtonController;
57     private RotationButton mRotationButton;
58     private int mWindowRotation = DEFAULT_ROTATE;
59     private Supplier<Integer> mWindowRotationSupplier = () -> mWindowRotation;
60 
61     @Before
setup()62     public void setup() {
63         MockitoAnnotations.initMocks(this);
64         mDependency.injectMockDependency(RotationLockController.class);
65 
66         final View view = new View(mContext);
67         mRotationButton = mock(RotationButton.class);
68         mRotationButtonController = new RotationButtonController(mContext,
69                 /* lightIconColor */ 0,
70                 /* darkIconColor */ 0,
71                 /* iconCcwStart0 */ 0,
72                 /* iconCcwStart90 */ 0,
73                 /* iconCwStart0 */ 0,
74                 /* iconCwStart90 */ 0,
75                 mWindowRotationSupplier
76         );
77         mRotationButtonController.setRotationButton(mRotationButton,
78                 new RotationButton.RotationButtonUpdatesCallback() {
79                     @Override
80                     public void onVisibilityChanged(boolean isVisible) {
81                     }
82 
83                     @Override
84                     public void onPositionChanged() {
85                     }
86                 });
87         // Due to a mockito issue, only spy the object after setting the initial state
88         mRotationButtonController = spy(mRotationButtonController);
89         doReturn(view).when(mRotationButton).getCurrentView();
90         doReturn(true).when(mRotationButton).acceptRotationProposal();
91     }
92 
93     @Test
testOnInvalidRotationProposal()94     public void testOnInvalidRotationProposal() {
95         mWindowRotation = DEFAULT_ROTATE + 1;
96         mRotationButtonController.onRotationProposal(DEFAULT_ROTATE, false /* isValid */);
97         verify(mRotationButtonController, times(1)).setRotateSuggestionButtonState(
98                 false /* visible */);
99     }
100 
101     @Test
testOnSameRotationProposal()102     public void testOnSameRotationProposal() {
103         mWindowRotation = DEFAULT_ROTATE;
104         mRotationButtonController.onRotationProposal(DEFAULT_ROTATE, true /* isValid */);
105         verify(mRotationButtonController, times(1)).setRotateSuggestionButtonState(
106                 false /* visible */);
107     }
108 
109     @Test
testOnRotationProposalShowButtonShowNav()110     public void testOnRotationProposalShowButtonShowNav() {
111         // No navigation bar should not call to set visibility state
112         mRotationButtonController.onBehaviorChanged(Display.DEFAULT_DISPLAY,
113                 WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
114         mRotationButtonController.onNavigationBarWindowVisibilityChange(false /* showing */);
115         verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
116                 false /* visible */);
117         verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
118                 true /* visible */);
119         mWindowRotation = DEFAULT_ROTATE + 1;
120 
121         // No navigation bar with rotation change should not call to set visibility state
122         mRotationButtonController.onRotationProposal(DEFAULT_ROTATE, true /* isValid */);
123         verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
124                 false /* visible */);
125         verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
126                 true /* visible */);
127 
128         // Since rotation has changed rotation should be pending, show mButton when showing nav bar
129         mRotationButtonController.onNavigationBarWindowVisibilityChange(true /* showing */);
130         verify(mRotationButtonController, times(1)).setRotateSuggestionButtonState(
131                 true /* visible */);
132     }
133 
134     @Test
testOnRotationProposalShowButton()135     public void testOnRotationProposalShowButton() {
136         // Navigation bar being visible should not call to set visibility state
137         mRotationButtonController.onNavigationBarWindowVisibilityChange(true /* showing */);
138         verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
139                 false /* visible */);
140         verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
141                 true /* visible */);
142         mWindowRotation = DEFAULT_ROTATE + 1;
143 
144         // Navigation bar is visible and rotation requested
145         mRotationButtonController.onRotationProposal(DEFAULT_ROTATE, true /* isValid */);
146         verify(mRotationButtonController, times(1)).setRotateSuggestionButtonState(
147                 true /* visible */);
148     }
149 }
150