1 /* 2 * Copyright (C) 2017 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.WindowInsets.Type.ime; 20 import static android.view.WindowInsets.Type.systemBars; 21 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.Mockito.never; 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.graphics.Insets; 29 import android.testing.AndroidTestingRunner; 30 import android.testing.TestableLooper; 31 import android.view.View; 32 import android.view.ViewGroup; 33 import android.view.WindowInsets; 34 import android.view.WindowInsetsController; 35 import android.widget.FrameLayout; 36 37 import androidx.test.filters.SmallTest; 38 39 import com.android.systemui.SysuiTestCase; 40 41 import org.junit.Before; 42 import org.junit.Rule; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.mockito.Mock; 46 import org.mockito.junit.MockitoJUnit; 47 import org.mockito.junit.MockitoRule; 48 49 @SmallTest 50 @RunWith(AndroidTestingRunner.class) 51 @TestableLooper.RunWithLooper() 52 public class KeyguardSecurityContainerTest extends SysuiTestCase { 53 private static final int SCREEN_WIDTH = 1600; 54 private static final int FAKE_MEASURE_SPEC = 55 View.MeasureSpec.makeMeasureSpec(SCREEN_WIDTH, View.MeasureSpec.EXACTLY); 56 57 @Rule 58 public MockitoRule mRule = MockitoJUnit.rule(); 59 60 @Mock 61 private WindowInsetsController mWindowInsetsController; 62 63 @Mock 64 private KeyguardSecurityViewFlipper mSecurityViewFlipper; 65 66 private KeyguardSecurityContainer mKeyguardSecurityContainer; 67 68 @Before setup()69 public void setup() { 70 // Needed here, otherwise when mKeyguardSecurityContainer is created below, it'll cache 71 // the real references (rather than the TestableResources that this call creates). 72 mContext.ensureTestableResources(); 73 FrameLayout.LayoutParams securityViewFlipperLayoutParams = new FrameLayout.LayoutParams( 74 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 75 76 when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController); 77 when(mSecurityViewFlipper.getLayoutParams()).thenReturn(securityViewFlipperLayoutParams); 78 mKeyguardSecurityContainer = new KeyguardSecurityContainer(getContext()); 79 mKeyguardSecurityContainer.mSecurityViewFlipper = mSecurityViewFlipper; 80 mKeyguardSecurityContainer.addView(mSecurityViewFlipper, new ViewGroup.LayoutParams( 81 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 82 } 83 84 @Test onMeasure_usesHalfWidthWithOneHandedModeEnabled()85 public void onMeasure_usesHalfWidthWithOneHandedModeEnabled() { 86 mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */true); 87 88 int halfWidthMeasureSpec = 89 View.MeasureSpec.makeMeasureSpec(SCREEN_WIDTH / 2, View.MeasureSpec.EXACTLY); 90 mKeyguardSecurityContainer.onMeasure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC); 91 92 verify(mSecurityViewFlipper).measure(halfWidthMeasureSpec, FAKE_MEASURE_SPEC); 93 } 94 95 @Test onMeasure_usesFullWidthWithOneHandedModeDisabled()96 public void onMeasure_usesFullWidthWithOneHandedModeDisabled() { 97 mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false); 98 99 mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC); 100 verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC); 101 } 102 103 @Test onMeasure_respectsViewInsets()104 public void onMeasure_respectsViewInsets() { 105 int imeInsetAmount = 100; 106 int systemBarInsetAmount = 10; 107 108 mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false); 109 110 Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount); 111 Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount); 112 113 WindowInsets insets = new WindowInsets.Builder() 114 .setInsets(ime(), imeInset) 115 .setInsetsIgnoringVisibility(systemBars(), systemBarInset) 116 .build(); 117 118 // It's reduced by the max of the systembar and IME, so just subtract IME inset. 119 int expectedHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec( 120 SCREEN_WIDTH - imeInsetAmount, View.MeasureSpec.EXACTLY); 121 122 mKeyguardSecurityContainer.onApplyWindowInsets(insets); 123 mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC); 124 verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, expectedHeightMeasureSpec); 125 } 126 127 @Test onMeasure_respectsViewInsets_largerSystembar()128 public void onMeasure_respectsViewInsets_largerSystembar() { 129 int imeInsetAmount = 0; 130 int systemBarInsetAmount = 10; 131 132 mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false); 133 134 Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount); 135 Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount); 136 137 WindowInsets insets = new WindowInsets.Builder() 138 .setInsets(ime(), imeInset) 139 .setInsetsIgnoringVisibility(systemBars(), systemBarInset) 140 .build(); 141 142 int expectedHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec( 143 SCREEN_WIDTH - systemBarInsetAmount, View.MeasureSpec.EXACTLY); 144 145 mKeyguardSecurityContainer.onApplyWindowInsets(insets); 146 mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC); 147 verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, expectedHeightMeasureSpec); 148 } 149 setupForUpdateKeyguardPosition(boolean oneHandedMode)150 private void setupForUpdateKeyguardPosition(boolean oneHandedMode) { 151 mKeyguardSecurityContainer.setOneHandedMode(oneHandedMode); 152 mKeyguardSecurityContainer.setOneHandedModeLeftAligned(true, false); 153 154 mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC); 155 mKeyguardSecurityContainer.layout(0, 0, SCREEN_WIDTH, SCREEN_WIDTH); 156 157 // Clear any interactions with the mock so we know the interactions definitely come from the 158 // below testing. 159 reset(mSecurityViewFlipper); 160 } 161 162 @Test setIsLeftAligned_movesKeyguard()163 public void setIsLeftAligned_movesKeyguard() { 164 setupForUpdateKeyguardPosition(/* oneHandedMode= */ true); 165 166 mKeyguardSecurityContainer.setOneHandedModeLeftAligned( 167 /* leftAligned= */false, /* animate= */false); 168 verify(mSecurityViewFlipper).setTranslationX( 169 mKeyguardSecurityContainer.getWidth() - mSecurityViewFlipper.getWidth()); 170 171 mKeyguardSecurityContainer.setOneHandedModeLeftAligned( 172 /* leftAligned= */true, /* animate= */false); 173 verify(mSecurityViewFlipper).setTranslationX(0.0f); 174 } 175 176 @Test setIsLeftAligned_doesntMoveTwoHandedKeyguard()177 public void setIsLeftAligned_doesntMoveTwoHandedKeyguard() { 178 setupForUpdateKeyguardPosition(/* oneHandedMode= */ false); 179 180 mKeyguardSecurityContainer.setOneHandedModeLeftAligned( 181 /* leftAligned= */false, /* animate= */false); 182 verify(mSecurityViewFlipper, never()).setTranslationX(anyInt()); 183 184 mKeyguardSecurityContainer.setOneHandedModeLeftAligned( 185 /* leftAligned= */true, /* animate= */false); 186 verify(mSecurityViewFlipper, never()).setTranslationX(anyInt()); 187 } 188 } 189