1 /* 2 * Copyright (C) 2022 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.reardisplay; 18 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertNotSame; 21 22 import static org.mockito.ArgumentMatchers.anyBoolean; 23 import static org.mockito.ArgumentMatchers.anyLong; 24 import static org.mockito.Mockito.reset; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.when; 27 28 import android.content.res.Configuration; 29 import android.content.res.Resources; 30 import android.hardware.devicestate.DeviceState; 31 import android.hardware.devicestate.DeviceStateManager; 32 import android.testing.TestableLooper; 33 import android.view.LayoutInflater; 34 import android.view.View; 35 import android.widget.TextView; 36 37 import androidx.test.ext.junit.runners.AndroidJUnit4; 38 import androidx.test.filters.SmallTest; 39 40 import com.android.systemui.SysuiTestCase; 41 import com.android.systemui.flags.FakeFeatureFlags; 42 import com.android.systemui.model.SysUiState; 43 import com.android.systemui.res.R; 44 import com.android.systemui.statusbar.CommandQueue; 45 import com.android.systemui.statusbar.phone.SystemUIDialog; 46 import com.android.systemui.util.concurrency.FakeExecutor; 47 import com.android.systemui.util.time.FakeSystemClock; 48 49 import org.junit.Before; 50 import org.junit.Test; 51 import org.junit.runner.RunWith; 52 import org.mockito.ArgumentCaptor; 53 import org.mockito.Mock; 54 import org.mockito.MockitoAnnotations; 55 56 @SmallTest 57 @RunWith(AndroidJUnit4.class) 58 @TestableLooper.RunWithLooper(setAsMainLooper = true) 59 public class RearDisplayDialogControllerTest extends SysuiTestCase { 60 61 @Mock 62 private CommandQueue mCommandQueue; 63 @Mock 64 private SystemUIDialog.Factory mSystemUIDialogFactory; 65 @Mock 66 private SystemUIDialog mSystemUIDialog; 67 private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags(); 68 @Mock 69 private SysUiState mSysUiState; 70 @Mock 71 private Resources mResources; 72 73 LayoutInflater mLayoutInflater = LayoutInflater.from(mContext); 74 75 private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); 76 77 private static final int CLOSED_BASE_STATE = 0; 78 private static final int OPEN_BASE_STATE = 1; 79 80 @Before setup()81 public void setup() { 82 MockitoAnnotations.initMocks(this); 83 84 when(mSysUiState.setFlag(anyLong(), anyBoolean())).thenReturn(mSysUiState); 85 when(mSystemUIDialogFactory.create()).thenReturn(mSystemUIDialog); 86 when(mSystemUIDialog.getContext()).thenReturn(mContext); 87 } 88 @Test testClosedDialogIsShown()89 public void testClosedDialogIsShown() { 90 RearDisplayDialogController controller = new RearDisplayDialogController( 91 mCommandQueue, 92 mFakeExecutor, 93 mResources, 94 mLayoutInflater, 95 mSystemUIDialogFactory); 96 controller.setDeviceStateManagerCallback(new TestDeviceStateManagerCallback()); 97 controller.setFoldedStates(new int[]{0}); 98 controller.setAnimationRepeatCount(0); 99 100 controller.showRearDisplayDialog(CLOSED_BASE_STATE); 101 verify(mSystemUIDialog).show(); 102 103 View container = getDialogViewContainer(); 104 TextView deviceClosedTitleTextView = container.findViewById( 105 R.id.rear_display_title_text_view); 106 assertEquals(deviceClosedTitleTextView.getText().toString(), 107 getContext().getResources().getString( 108 R.string.rear_display_folded_bottom_sheet_title)); 109 } 110 111 @Test testClosedDialogIsRefreshedOnConfigurationChange()112 public void testClosedDialogIsRefreshedOnConfigurationChange() { 113 RearDisplayDialogController controller = new RearDisplayDialogController( 114 mCommandQueue, 115 mFakeExecutor, 116 mResources, 117 mLayoutInflater, 118 mSystemUIDialogFactory); 119 controller.setDeviceStateManagerCallback(new TestDeviceStateManagerCallback()); 120 controller.setFoldedStates(new int[]{0}); 121 controller.setAnimationRepeatCount(0); 122 123 controller.showRearDisplayDialog(CLOSED_BASE_STATE); 124 verify(mSystemUIDialog).show(); 125 View container = getDialogViewContainer(); 126 TextView deviceClosedTitleTextView = container.findViewById( 127 R.id.rear_display_title_text_view); 128 129 reset(mSystemUIDialog); 130 when(mSystemUIDialog.isShowing()).thenReturn(true); 131 when(mSystemUIDialog.getContext()).thenReturn(mContext); 132 133 controller.onConfigChanged(new Configuration()); 134 TextView deviceClosedTitleTextView2 = container.findViewById( 135 R.id.rear_display_title_text_view); 136 137 assertNotSame(deviceClosedTitleTextView, deviceClosedTitleTextView2); 138 } 139 140 @Test testOpenDialogIsShown()141 public void testOpenDialogIsShown() { 142 RearDisplayDialogController controller = new RearDisplayDialogController( 143 mCommandQueue, 144 mFakeExecutor, 145 mResources, 146 mLayoutInflater, 147 mSystemUIDialogFactory); 148 controller.setDeviceStateManagerCallback(new TestDeviceStateManagerCallback()); 149 controller.setFoldedStates(new int[]{0}); 150 controller.setAnimationRepeatCount(0); 151 152 controller.showRearDisplayDialog(OPEN_BASE_STATE); 153 154 verify(mSystemUIDialog).show(); 155 View container = getDialogViewContainer(); 156 TextView deviceClosedTitleTextView = container.findViewById( 157 R.id.rear_display_title_text_view); 158 assertEquals(deviceClosedTitleTextView.getText().toString(), 159 getContext().getResources().getString( 160 R.string.rear_display_unfolded_bottom_sheet_title)); 161 } 162 getDialogViewContainer()163 private View getDialogViewContainer() { 164 ArgumentCaptor<View> viewCaptor = ArgumentCaptor.forClass(View.class); 165 verify(mSystemUIDialog).setView(viewCaptor.capture()); 166 167 return viewCaptor.getValue(); 168 } 169 /** 170 * Empty device state manager callbacks, so we can verify that the correct 171 * dialogs are being created regardless of device state of the test device. 172 */ 173 private static class TestDeviceStateManagerCallback implements 174 DeviceStateManager.DeviceStateCallback { 175 176 @Override onDeviceStateChanged(DeviceState state)177 public void onDeviceStateChanged(DeviceState state) { } 178 } 179 } 180