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