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