1 /* 2 * Copyright (C) 2008 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.internal.policy.impl; 18 19 import android.content.Context; 20 import com.android.internal.telephony.IccCard; 21 import android.test.AndroidTestCase; 22 import android.view.View; 23 import android.view.KeyEvent; 24 import com.android.internal.widget.LockPatternUtils; 25 import com.google.android.collect.Lists; 26 27 import java.util.List; 28 29 /** 30 * Tests for {@link com.android.internal.policy.impl.LockPatternKeyguardView}, 31 * which handles the management of screens while the keyguard is showing. 32 */ 33 public class LockPatternKeyguardViewTest extends AndroidTestCase { 34 private MockUpdateMonitor mUpdateMonitor; 35 private LockPatternUtils mLockPatternUtils; 36 private TestableLockPatternKeyguardView mLPKV; 37 private MockKeyguardCallback mKeyguardViewCallback; 38 39 private static class MockUpdateMonitor extends KeyguardUpdateMonitor { 40 41 public IccCard.State simState = IccCard.State.READY; 42 public boolean inPortrait = false; 43 public boolean keyboardOpen = false; 44 MockUpdateMonitor(Context context)45 private MockUpdateMonitor(Context context) { 46 super(context); 47 } 48 49 @Override getSimState()50 public IccCard.State getSimState() { 51 return simState; 52 } 53 54 @Override isInPortrait()55 public boolean isInPortrait() { 56 return inPortrait; 57 } 58 59 @Override isKeyboardOpen()60 public boolean isKeyboardOpen() { 61 return keyboardOpen; 62 } 63 64 @Override queryInPortrait()65 boolean queryInPortrait() { 66 return inPortrait; 67 } 68 69 @Override queryKeyboardOpen()70 boolean queryKeyboardOpen() { 71 return keyboardOpen; 72 } 73 } 74 75 private static class MockLockPatternUtils extends LockPatternUtils { 76 boolean isLockPatternEnabled = true; 77 public boolean isPermanentlyLocked = false; 78 MockLockPatternUtils()79 public MockLockPatternUtils() { 80 super(null); 81 } 82 83 @Override isLockPatternEnabled()84 public boolean isLockPatternEnabled() { 85 return isLockPatternEnabled; 86 } 87 88 @Override setLockPatternEnabled(boolean lockPatternEnabled)89 public void setLockPatternEnabled(boolean lockPatternEnabled) { 90 isLockPatternEnabled = lockPatternEnabled; 91 } 92 93 @Override isPermanentlyLocked()94 public boolean isPermanentlyLocked() { 95 return isPermanentlyLocked; 96 } 97 setPermanentlyLocked(boolean permanentlyLocked)98 public void setPermanentlyLocked(boolean permanentlyLocked) { 99 isPermanentlyLocked = permanentlyLocked; 100 } 101 } 102 103 private static class MockKeyguardScreen extends View implements KeyguardScreen { 104 105 private int mOnPauseCount = 0; 106 private int mOnResumeCount = 0; 107 private int mCleanupCount = 0; 108 MockKeyguardScreen(Context context)109 private MockKeyguardScreen(Context context) { 110 super(context); 111 setFocusable(true); 112 } 113 114 /** {@inheritDoc} */ needsInput()115 public boolean needsInput() { 116 return false; 117 } 118 119 /** {@inheritDoc} */ onPause()120 public void onPause() { 121 mOnPauseCount++; 122 } 123 124 /** {@inheritDoc} */ onResume()125 public void onResume() { 126 mOnResumeCount++; 127 } 128 129 /** {@inheritDoc} */ cleanUp()130 public void cleanUp() { 131 mCleanupCount++; 132 } 133 getOnPauseCount()134 public int getOnPauseCount() { 135 return mOnPauseCount; 136 } 137 getOnResumeCount()138 public int getOnResumeCount() { 139 return mOnResumeCount; 140 } 141 getCleanupCount()142 public int getCleanupCount() { 143 return mCleanupCount; 144 } 145 } 146 147 /** 148 * Allows us to inject the lock and unlock views to simulate their behavior 149 * and detect their creation. 150 */ 151 private static class TestableLockPatternKeyguardView extends LockPatternKeyguardView { 152 private List<MockKeyguardScreen> mInjectedLockScreens; 153 private List<MockKeyguardScreen> mInjectedUnlockScreens; 154 155 156 TestableLockPatternKeyguardView(Context context, KeyguardUpdateMonitor updateMonitor, LockPatternUtils lockPatternUtils, KeyguardWindowController controller)157 private TestableLockPatternKeyguardView(Context context, KeyguardUpdateMonitor updateMonitor, 158 LockPatternUtils lockPatternUtils, KeyguardWindowController controller) { 159 super(context, updateMonitor, lockPatternUtils, controller); 160 } 161 162 @Override createLockScreen()163 View createLockScreen() { 164 final MockKeyguardScreen newView = new MockKeyguardScreen(getContext()); 165 if (mInjectedLockScreens == null) mInjectedLockScreens = Lists.newArrayList(); 166 mInjectedLockScreens.add(newView); 167 return newView; 168 } 169 170 @Override createUnlockScreenFor(UnlockMode unlockMode)171 View createUnlockScreenFor(UnlockMode unlockMode) { 172 final MockKeyguardScreen newView = new MockKeyguardScreen(getContext()); 173 if (mInjectedUnlockScreens == null) mInjectedUnlockScreens = Lists.newArrayList(); 174 mInjectedUnlockScreens.add(newView); 175 return newView; 176 } 177 getInjectedLockScreens()178 public List<MockKeyguardScreen> getInjectedLockScreens() { 179 return mInjectedLockScreens; 180 } 181 getInjectedUnlockScreens()182 public List<MockKeyguardScreen> getInjectedUnlockScreens() { 183 return mInjectedUnlockScreens; 184 } 185 } 186 187 private static class MockKeyguardCallback implements KeyguardViewCallback { 188 189 private int mPokeWakelockCount = 0; 190 private int mKeyguardDoneCount = 0; 191 pokeWakelock()192 public void pokeWakelock() { 193 mPokeWakelockCount++; 194 } 195 pokeWakelock(int millis)196 public void pokeWakelock(int millis) { 197 mPokeWakelockCount++; 198 } 199 keyguardDone(boolean authenticated)200 public void keyguardDone(boolean authenticated) { 201 mKeyguardDoneCount++; 202 } 203 keyguardDoneDrawing()204 public void keyguardDoneDrawing() { 205 206 } 207 getPokeWakelockCount()208 public int getPokeWakelockCount() { 209 return mPokeWakelockCount; 210 } 211 getKeyguardDoneCount()212 public int getKeyguardDoneCount() { 213 return mKeyguardDoneCount; 214 } 215 } 216 217 @Override setUp()218 protected void setUp() throws Exception { 219 super.setUp(); 220 mUpdateMonitor = new MockUpdateMonitor(getContext()); 221 mLockPatternUtils = new MockLockPatternUtils(); 222 223 mLPKV = new TestableLockPatternKeyguardView(getContext(), mUpdateMonitor, 224 mLockPatternUtils, new KeyguardWindowController() { 225 public void setNeedsInput(boolean needsInput) { 226 } 227 }); 228 mKeyguardViewCallback = new MockKeyguardCallback(); 229 mLPKV.setCallback(mKeyguardViewCallback); 230 } 231 testStateAfterCreatedWhileScreenOff()232 public void testStateAfterCreatedWhileScreenOff() { 233 234 assertEquals(1, mLPKV.getInjectedLockScreens().size()); 235 assertEquals(1, mLPKV.getInjectedUnlockScreens().size()); 236 237 MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0); 238 MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0); 239 240 assertEquals(0, lockScreen.getOnPauseCount()); 241 assertEquals(0, lockScreen.getOnResumeCount()); 242 assertEquals(0, lockScreen.getCleanupCount()); 243 244 assertEquals(0, unlockScreen.getOnPauseCount()); 245 assertEquals(0, unlockScreen.getOnResumeCount()); 246 assertEquals(0, unlockScreen.getCleanupCount()); 247 248 assertEquals(0, mKeyguardViewCallback.getPokeWakelockCount()); 249 assertEquals(0, mKeyguardViewCallback.getKeyguardDoneCount()); 250 } 251 testWokenByNonMenuKey()252 public void testWokenByNonMenuKey() { 253 mLPKV.wakeWhenReadyTq(0); 254 255 // should have poked the wakelock to turn on the screen 256 assertEquals(1, mKeyguardViewCallback.getPokeWakelockCount()); 257 258 // shouldn't be any additional views created 259 assertEquals(1, mLPKV.getInjectedLockScreens().size()); 260 assertEquals(1, mLPKV.getInjectedUnlockScreens().size()); 261 MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0); 262 MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0); 263 264 // lock screen should be only visible one 265 assertEquals(View.VISIBLE, lockScreen.getVisibility()); 266 assertEquals(View.GONE, unlockScreen.getVisibility()); 267 268 // on resume not called until screen turns on 269 assertEquals(0, lockScreen.getOnPauseCount()); 270 assertEquals(0, lockScreen.getOnResumeCount()); 271 assertEquals(0, lockScreen.getCleanupCount()); 272 273 assertEquals(0, unlockScreen.getOnPauseCount()); 274 assertEquals(0, unlockScreen.getOnResumeCount()); 275 assertEquals(0, unlockScreen.getCleanupCount()); 276 277 // simulate screen turning on 278 mLPKV.onScreenTurnedOn(); 279 280 assertEquals(0, lockScreen.getOnPauseCount()); 281 assertEquals(1, lockScreen.getOnResumeCount()); 282 assertEquals(0, lockScreen.getCleanupCount()); 283 284 assertEquals(0, unlockScreen.getOnPauseCount()); 285 assertEquals(0, unlockScreen.getOnResumeCount()); 286 assertEquals(0, unlockScreen.getCleanupCount()); 287 } 288 testWokenByMenuKeyWhenPatternSet()289 public void testWokenByMenuKeyWhenPatternSet() { 290 assertEquals(true, mLockPatternUtils.isLockPatternEnabled()); 291 292 mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU); 293 294 // should have poked the wakelock to turn on the screen 295 assertEquals(1, mKeyguardViewCallback.getPokeWakelockCount()); 296 297 // shouldn't be any additional views created 298 assertEquals(1, mLPKV.getInjectedLockScreens().size()); 299 assertEquals(1, mLPKV.getInjectedUnlockScreens().size()); 300 MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0); 301 MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0); 302 303 // unlock screen should be only visible one 304 assertEquals(View.GONE, lockScreen.getVisibility()); 305 assertEquals(View.VISIBLE, unlockScreen.getVisibility()); 306 } 307 testScreenRequestsRecreation()308 public void testScreenRequestsRecreation() { 309 mLPKV.wakeWhenReadyTq(0); 310 mLPKV.onScreenTurnedOn(); 311 312 assertEquals(1, mLPKV.getInjectedLockScreens().size()); 313 assertEquals(1, mLPKV.getInjectedUnlockScreens().size()); 314 MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0); 315 316 assertEquals(0, lockScreen.getOnPauseCount()); 317 assertEquals(1, lockScreen.getOnResumeCount()); 318 319 // simulate screen asking to be recreated 320 mLPKV.mKeyguardScreenCallback.recreateMe(); 321 322 // should have been recreated 323 assertEquals(2, mLPKV.getInjectedLockScreens().size()); 324 assertEquals(2, mLPKV.getInjectedUnlockScreens().size()); 325 326 // both old screens should have been cleaned up 327 assertEquals(1, mLPKV.getInjectedLockScreens().get(0).getCleanupCount()); 328 assertEquals(1, mLPKV.getInjectedUnlockScreens().get(0).getCleanupCount()); 329 330 // old lock screen should have been paused 331 assertEquals(1, mLPKV.getInjectedLockScreens().get(0).getOnPauseCount()); 332 assertEquals(0, mLPKV.getInjectedUnlockScreens().get(0).getOnPauseCount()); 333 334 // new lock screen should have been resumed 335 assertEquals(1, mLPKV.getInjectedLockScreens().get(1).getOnResumeCount()); 336 assertEquals(0, mLPKV.getInjectedUnlockScreens().get(1).getOnResumeCount()); 337 } 338 testMenuDoesntGoToUnlockScreenOnWakeWhenPukLocked()339 public void testMenuDoesntGoToUnlockScreenOnWakeWhenPukLocked() { 340 // PUK locked 341 mUpdateMonitor.simState = IccCard.State.PUK_REQUIRED; 342 343 // wake by menu 344 mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU); 345 346 assertEquals(1, mLPKV.getInjectedLockScreens().size()); 347 assertEquals(1, mLPKV.getInjectedUnlockScreens().size()); 348 MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0); 349 MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0); 350 351 // lock screen should be only visible one 352 assertEquals(View.VISIBLE, lockScreen.getVisibility()); 353 assertEquals(View.GONE, unlockScreen.getVisibility()); 354 } 355 testMenuGoesToLockScreenWhenDeviceNotSecure()356 public void testMenuGoesToLockScreenWhenDeviceNotSecure() { 357 mLockPatternUtils.setLockPatternEnabled(false); 358 359 // wake by menu 360 mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU); 361 362 assertEquals(1, mLPKV.getInjectedLockScreens().size()); 363 assertEquals(1, mLPKV.getInjectedUnlockScreens().size()); 364 MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0); 365 MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0); 366 367 // lock screen should be only visible one 368 assertEquals(View.VISIBLE, lockScreen.getVisibility()); 369 assertEquals(View.GONE, unlockScreen.getVisibility()); 370 } 371 } 372