KeyguardHostView.java revision dfb57cdcfc6a1fd48395c13af98ecc2722fd5254
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2012 The Android Open Source Project 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * you may not use this file except in compliance with the License. 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * You may obtain a copy of the License at 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch * Unless required by applicable law or agreed to in writing, software 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package com.android.internal.policy.impl.keyguard; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.app.Activity; 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)import android.app.ActivityManager; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.app.ActivityOptions; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.app.AlertDialog; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.app.SearchManager; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.app.admin.DevicePolicyManager; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.appwidget.AppWidgetHost; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.appwidget.AppWidgetHostView; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.appwidget.AppWidgetManager; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.appwidget.AppWidgetProviderInfo; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.ComponentName; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.Context; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.Intent; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.IntentSender; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.pm.PackageManager.NameNotFoundException; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.pm.UserInfo; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.res.Resources; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.graphics.Canvas; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.graphics.Rect; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.media.RemoteControlClient; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.os.Looper; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.os.Parcel; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.os.Parcelable; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.SystemClock; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.UserHandle; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.UserManager; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.provider.Settings; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.AttributeSet; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.Log; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.util.Slog; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.KeyEvent; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.LayoutInflater; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.view.MotionEvent; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.view.View; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.view.WindowManager; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.view.animation.AnimationUtils; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.widget.RemoteViews.OnClickHandler; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import com.android.internal.R; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import com.android.internal.policy.impl.keyguard.KeyguardUpdateMonitor.DisplayClientState; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.android.internal.widget.LockPatternUtils; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.File; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import java.util.List; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public class KeyguardHostView extends KeyguardViewBase { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static final String TAG = "KeyguardHostView"; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Transport control states. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static final int TRANSPORT_GONE = 0; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static final int TRANSPORT_INVISIBLE = 1; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static final int TRANSPORT_VISIBLE = 2; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private int mTransportState = TRANSPORT_GONE; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Use this to debug all of keyguard 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static boolean DEBUG = KeyguardViewMediator.DEBUG; 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public static boolean DEBUGXPORT = true; // debug music transport control 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Found in KeyguardAppWidgetPickActivity.java 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static final int APPWIDGET_HOST_ID = 0x4B455947; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private final int MAX_WIDGETS = 5; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private AppWidgetHost mAppWidgetHost; 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private AppWidgetManager mAppWidgetManager; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardWidgetPager mAppWidgetContainer; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardSecurityViewFlipper mSecurityViewContainer; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardSelectorView mKeyguardSelectorView; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardTransportControlView mTransportControl; 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private boolean mIsVerifyUnlockOnly; 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private int mAppWidgetToShow; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private boolean mCheckAppWidgetConsistencyOnBootCompleted = false; 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private boolean mCleanupAppWidgetsOnBootCompleted = false; 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected OnDismissAction mDismissAction; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected int mFailedAttempts; 1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch private LockPatternUtils mLockPatternUtils; 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private KeyguardSecurityModel mSecurityModel; 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private KeyguardViewStateManager mViewStateManager; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private Rect mTempRect = new Rect(); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private int mDisabledFeatures; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private boolean mCameraDisabled; 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private boolean mSafeModeEnabled; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private boolean mUserSetupCompleted; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // User for whom this host view was created. Final because we should never change the 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // id without reconstructing an instance of KeyguardHostView. See note below... 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private final int mUserId; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected int mClientGeneration; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /*package*/ interface UserSwitcherCallback { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void hideSecurityView(int duration); 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void showSecurityView(); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void showUnlockHint(); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void userActivity(); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /*package*/ interface OnDismissAction { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* returns true if the dismiss should be deferred */ 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) boolean onDismiss(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public KeyguardHostView(Context context) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this(context, null); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public KeyguardHostView(Context context, AttributeSet attrs) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) super(context, attrs); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (DEBUG) Log.e(TAG, "KeyguardHostView()"); 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mLockPatternUtils = new LockPatternUtils(context); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note: This depends on KeyguardHostView getting reconstructed every time the 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // user switches, since mUserId will be used for the entire session. 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Once created, keyguard should *never* re-use this instance with another user. 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In other words, mUserId should never change - hence it's marked final. 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mUserId = mLockPatternUtils.getCurrentUser(); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevicePolicyManager dpm = 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dpm != null) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mDisabledFeatures = getDisabledFeatures(dpm); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mCameraDisabled = dpm.getCameraDisabled(null); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled(); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These need to be created with the user context... 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Context userContext = null; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final String packageName = "system"; 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch userContext = mContext.createPackageContextAsUser(packageName, 0, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new UserHandle(mUserId)); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } catch (NameNotFoundException e) { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) e.printStackTrace(); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should never happen, but it's better to have no widgets than to crash. 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) userContext = context; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetHost = new AppWidgetHost(userContext, APPWIDGET_HOST_ID, mOnClickHandler, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Looper.myLooper()); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleanupAppWidgetIds(); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetManager = AppWidgetManager.getInstance(userContext); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mSecurityModel = new KeyguardSecurityModel(context); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mViewStateManager = new KeyguardViewStateManager(this); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(), 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Ensure we have the current state *before* we call showAppropriateWidgetPage() 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getInitialTransportState(); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mSafeModeEnabled) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.v(TAG, "Keyguard widgets disabled by safe mode"); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) { 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.v(TAG, "Keyguard widgets disabled by DPM"); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.v(TAG, "Keyguard secure camera disabled by DPM"); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void getInitialTransportState() { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayClientState dcs = KeyguardUpdateMonitor.getInstance(mContext) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .getCachedDisplayClientState(); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mTransportState = (dcs.clearing ? TRANSPORT_GONE : 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (isMusicPlaying(dcs.playbackState) ? TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE)); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DEBUG) Log.v(TAG, "Initial transport state: " 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) + mTransportState + ", pbstate=" + dcs.playbackState); 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void cleanupAppWidgetIds() { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since this method may delete a widget (which we can't do until boot completed) we 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // may have to defer it until after boot complete. 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mCleanupAppWidgetsOnBootCompleted = true; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!mSafeModeEnabled && !widgetsDisabledByDpm()) { 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clean up appWidgetIds that are bound to lockscreen, but not actually used 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is only to clean up after another bug: we used to not call 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // deleteAppWidgetId when a user manually deleted a widget in keyguard. This code 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that are triggered by deleteAppWidgetId, which is why we're doing this 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets(); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds(); 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int appWidgetId = appWidgetIdsBoundToHost[i]; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id " 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) + appWidgetId); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetHost.deleteAppWidgetId(appWidgetId); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static boolean contains(int[] array, int target) { 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int value : array) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (value == target) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks = 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new KeyguardUpdateMonitorCallback() { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onBootCompleted() { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mCheckAppWidgetConsistencyOnBootCompleted) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) checkAppWidgetConsistency(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mSwitchPageRunnable.run(); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mCheckAppWidgetConsistencyOnBootCompleted = false; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mCleanupAppWidgetsOnBootCompleted) { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleanupAppWidgetIds(); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mCleanupAppWidgetsOnBootCompleted = false; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onUserSwitchComplete(int userId) { 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mKeyguardMultiUserSelectorView != null) { 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mKeyguardMultiUserSelectorView.finalizeActiveUserView(true); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void onMusicClientIdChanged( 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int clientGeneration, boolean clearing, android.app.PendingIntent intent) { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set transport state to invisible until we know music is playing (below) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DEBUGXPORT && (mClientGeneration != clientGeneration || clearing)) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log.v(TAG, (clearing ? "hide" : "show") + " transport, gen:" + clientGeneration); 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mClientGeneration = clientGeneration; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final int newState = (clearing ? TRANSPORT_GONE 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : (mTransportState == TRANSPORT_VISIBLE ? 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE)); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (newState != mTransportState) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mTransportState = newState; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed"); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardHostView.this.post(mSwitchPageRunnable); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onMusicPlaybackStateChanged(int playbackState, long eventTime) { 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DEBUGXPORT) Log.v(TAG, "music state changed: " + playbackState); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mTransportState != TRANSPORT_GONE) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final int newState = (isMusicPlaying(playbackState) ? 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (newState != mTransportState) { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mTransportState = newState; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed"); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardHostView.this.post(mSwitchPageRunnable); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static final boolean isMusicPlaying(int playbackState) { 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should agree with the list in AudioService.isPlaystateActive() 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (playbackState) { 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case RemoteControlClient.PLAYSTATE_PLAYING: 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case RemoteControlClient.PLAYSTATE_BUFFERING: 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case RemoteControlClient.PLAYSTATE_FAST_FORWARDING: 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case RemoteControlClient.PLAYSTATE_REWINDING: 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS: 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS: 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private SlidingChallengeLayout mSlidingChallengeLayout; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public boolean onTouchEvent(MotionEvent ev) { 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) boolean result = super.onTouchEvent(ev); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mTempRect.set(0, 0, 0, 0); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ev.offsetLocation(mTempRect.left, mTempRect.top); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = mSecurityViewContainer.dispatchTouchEvent(ev) || result; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ev.offsetLocation(-mTempRect.left, -mTempRect.top); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected void dispatchDraw(Canvas canvas) { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) super.dispatchDraw(canvas); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mViewMediatorCallback != null) { 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mViewMediatorCallback.keyguardDoneDrawing(); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private int getWidgetPosition(int id) { 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final KeyguardWidgetPager appWidgetContainer = mAppWidgetContainer; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int children = appWidgetContainer.getChildCount(); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < children; i++) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final View content = appWidgetContainer.getWidgetPageAt(i).getContent(); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (content != null && content.getId() == id) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (content == null) { 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Attempt to track down bug #8886916 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.w(TAG, "*** Null content at " + "i=" + i + ",id=" + id + ",N=" + children); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected void onFinishInflate() { 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Grab instances of and make any necessary changes to the main layouts. Create 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // view state manager and wire up necessary listeners / callbacks. 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setVisibility(VISIBLE); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setCallbacks(mWidgetCallbacks); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setMinScale(0.5f); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch mSlidingChallengeLayout = (SlidingChallengeLayout) findViewById(R.id.sliding_layout); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mSlidingChallengeLayout != null) { 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mSlidingChallengeLayout.setOnChallengeScrolledListener(mViewStateManager); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setViewStateManager(mViewStateManager); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChallengeLayout challenge = mSlidingChallengeLayout != null ? mSlidingChallengeLayout : 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ChallengeLayout) findViewById(R.id.multi_pane_challenge); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenge.setOnBouncerStateChangedListener(mViewStateManager); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mAppWidgetContainer.setBouncerAnimationDuration(challenge.getBouncerAnimationDuration()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mViewStateManager.setPagedView(mAppWidgetContainer); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mViewStateManager.setChallengeLayout(challenge); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mViewStateManager.setSecurityViewContainer(mSecurityViewContainer); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setBackButtonEnabled(false); 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) addDefaultWidgets(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) addWidgetsFromSettings(); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shouldEnableAddWidget()) { 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setAddWidgetEnabled(false); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) checkAppWidgetConsistency(); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mSwitchPageRunnable.run(); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This needs to be called after the pages are all added. 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mViewStateManager.showUsabilityHints(); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showPrimarySecurityScreen(false); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) updateSecurityViews(); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private void setBackButtonEnabled(boolean enabled) { 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (mContext instanceof Activity) return; // always enabled in activity mode 3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch setSystemUiVisibility(enabled ? 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_BACK : 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private boolean shouldEnableAddWidget() { 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return numWidgets() < MAX_WIDGETS && mUserSetupCompleted; 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private int getDisabledFeatures(DevicePolicyManager dpm) { 4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dpm != null) { 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int currentUser = mLockPatternUtils.getCurrentUser(); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return disabledFeatures; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private boolean widgetsDisabledByDpm() { 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private boolean cameraDisabledByDpm() { 4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return mCameraDisabled 4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0; 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void updateSecurityViews() { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int children = mSecurityViewContainer.getChildCount(); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < children; i++) { 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) updateSecurityView(mSecurityViewContainer.getChildAt(i)); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private void updateSecurityView(View view) { 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (view instanceof KeyguardSecurityView) { 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardSecurityView ksv = (KeyguardSecurityView) view; 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ksv.setKeyguardCallback(mCallback); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ksv.setLockPatternUtils(mLockPatternUtils); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mViewStateManager.isBouncing()) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ksv.showBouncer(0); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ksv.hideBouncer(0); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.w(TAG, "View " + view + " is not a KeyguardSecurityView"); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void setLockPatternUtils(LockPatternUtils utils) { 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mSecurityModel.setLockPatternUtils(utils); 4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mLockPatternUtils = utils; 4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch updateSecurityViews(); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @Override 4537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch protected void onAttachedToWindow() { 4547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch super.onAttachedToWindow(); 4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mAppWidgetHost.startListening(); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected void onDetachedFromWindow() { 4617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch super.onDetachedFromWindow(); 4627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mAppWidgetHost.stopListening(); 4637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks); 4647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void addWidget(AppWidgetHostView view, int pageIndex) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mAppWidgetContainer.addWidget(view, pageIndex); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardWidgetPager.Callbacks mWidgetCallbacks 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) = new KeyguardWidgetPager.Callbacks() { 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void userActivity() { 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardHostView.this.userActivity(); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onUserActivityTimeoutChanged() { 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardHostView.this.onUserActivityTimeoutChanged(); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onAddView(View v) { 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shouldEnableAddWidget()) { 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setAddWidgetEnabled(false); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onRemoveView(View v, boolean deletePermanently) { 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (deletePermanently) { 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId(); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID && 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) { 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetHost.deleteAppWidgetId(appWidgetId); 496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onRemoveViewAnimationCompleted() { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (shouldEnableAddWidget()) { 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mAppWidgetContainer.setAddWidgetEnabled(true); 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public void initializeSwitchingUserState(boolean switching) { 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!switching && mKeyguardMultiUserSelectorView != null) { 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mKeyguardMultiUserSelectorView.finalizeActiveUserView(false); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void userActivity() { 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mViewMediatorCallback != null) { 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mViewMediatorCallback.userActivity(); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void onUserActivityTimeoutChanged() { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mViewMediatorCallback != null) { 5227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mViewMediatorCallback.onUserActivityTimeoutChanged(); 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public long getUserActivityTimeout() { 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Currently only considering user activity timeouts needed by widgets. 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Could also take into account longer timeouts for certain security views. 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mAppWidgetContainer != null) { 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return mAppWidgetContainer.getUserActivityTimeout(); 5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() { 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void userActivity(long timeout) { 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mViewMediatorCallback != null) { 5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mViewMediatorCallback.userActivity(timeout); 5417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void dismiss(boolean authenticated) { 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showNextSecurityScreenOrFinish(authenticated); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public boolean isVerifyUnlockOnly() { 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return mIsVerifyUnlockOnly; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void reportSuccessfulUnlockAttempt() { 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts(); 5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mLockPatternUtils.reportSuccessfulPasswordAttempt(); 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void reportFailedUnlockAttempt() { 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mCurrentSecuritySelection == SecurityMode.Biometric) { 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt(); 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardHostView.this.reportFailedUnlockAttempt(); 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public int getFailedAttempts() { 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(); 5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void showBackupSecurity() { 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardHostView.this.showBackupSecurityScreen(); 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void setOnDismissAction(OnDismissAction action) { 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardHostView.this.setOnDismissAction(action); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void showDialog(String title, String message) { 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final AlertDialog dialog = new AlertDialog.Builder(mContext) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .setTitle(title) 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .setMessage(message) 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .setNeutralButton(com.android.internal.R.string.ok, null) 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .create(); 5877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!(mContext instanceof Activity)) { 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dialog.show(); 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void showTimeoutDialog() { 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000; 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int messageId = 0; 5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (mSecurityModel.getSecurityMode()) { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Pattern: 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message; 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PIN: 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message; 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Password: 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messageId = R.string.kg_too_many_failed_password_attempts_dialog_message; 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (messageId != 0) { 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final String message = mContext.getString(messageId, 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(), 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timeoutInSeconds); 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showDialog(null, message); 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void showAlmostAtWipeDialog(int attempts, int remaining) { 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000; 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe, 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attempts, remaining); 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showDialog(null, message); 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void showWipeDialog(int attempts) { 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts); 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showDialog(null, message); 6277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private void showAlmostAtAccountLoginDialog() { 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000; 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT; 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login, 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds); 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showDialog(null, message); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void reportFailedUnlockAttempt() { 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); 6407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time 6417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SecurityMode mode = mSecurityModel.getSecurityMode(); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern; 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager() 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser()); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT; 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ? 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (failedAttemptsBeforeWipe - failedAttempts) 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : Integer.MAX_VALUE; // because DPM returns 0 if no restriction 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) boolean showTimeout = false; 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) { 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we reach this code, it means the user has installed a DevicePolicyManager 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that requests device wipe after N attempts. Once we get below the grace 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // period, we'll post this dialog every time as a clear warning until the 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // bombshell hits and the device is wiped. 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (remainingBeforeWipe > 0) { 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe); 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Too many attempts. The device will be wiped shortly. 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Slog.i(TAG, "Too many unlock attempts; device will be wiped!"); 6687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch showWipeDialog(failedAttempts); 6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showTimeout = 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0; 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (usingPattern && mEnableFallback) { 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (failedAttempts == failedAttemptWarning) { 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showAlmostAtAccountLoginDialog(); 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showTimeout = false; // don't show both dialogs 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) { 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mLockPatternUtils.setPermanentlyLocked(true); 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showSecurityScreen(SecurityMode.Account); 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // don't show timeout dialog because we show account unlock screen next 6812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch showTimeout = false; 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor.reportFailedUnlockAttempt(); 6867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mLockPatternUtils.reportFailedPasswordAttempt(); 6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (showTimeout) { 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showTimeoutDialog(); 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Shows the primary security screen for the user. This will be either the multi-selector 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * or the user's security method. 6957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * @param turningOff true if the device is being turned off 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void showPrimarySecurityScreen(boolean turningOff) { 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SecurityMode securityMode = mSecurityModel.getSecurityMode(); 6992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")"); 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!turningOff && 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) { 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we're not turning off, then allow biometric alternate. 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We'll reload it when the device comes back on. 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) securityMode = mSecurityModel.getAlternateFor(securityMode); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showSecurityScreen(securityMode); 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Shows the backup security screen for the current security mode. This could be used for 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * password recovery screens but is currently only used for pattern unlock to show the 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * account unlock screen and biometric unlock to show the user's normal unlock. 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void showBackupSecurityScreen() { 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DEBUG) Log.d(TAG, "showBackupSecurity()"); 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection); 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showSecurityScreen(backup); 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public boolean showNextSecurityScreenIfPresent() { 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SecurityMode securityMode = mSecurityModel.getSecurityMode(); 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow an alternate, such as biometric unlock 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) securityMode = mSecurityModel.getAlternateFor(securityMode); 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (SecurityMode.None == securityMode) { 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showSecurityScreen(securityMode); // switch to the alternate security view 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void showNextSecurityScreenOrFinish(boolean authenticated) { 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")"); 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) boolean finish = false; 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (SecurityMode.None == mCurrentSecuritySelection) { 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SecurityMode securityMode = mSecurityModel.getSecurityMode(); 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow an alternate, such as biometric unlock 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) securityMode = mSecurityModel.getAlternateFor(securityMode); 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (SecurityMode.None == securityMode) { 7407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch finish = true; // no security required 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showSecurityScreen(securityMode); // switch to the alternate security view 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (authenticated) { 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (mCurrentSecuritySelection) { 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Pattern: 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Password: 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PIN: 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Account: 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Biometric: 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) finish = true; 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SimPin: 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SimPuk: 7567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home 7577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SecurityMode securityMode = mSecurityModel.getSecurityMode(); 7587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (securityMode != SecurityMode.None) { 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showSecurityScreen(securityMode); 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) finish = true; 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 764ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe"); 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) showPrimarySecurityScreen(false); 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 7717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch showPrimarySecurityScreen(false); 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (finish) { 7747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the alternate unlock was suppressed, it can now be safely 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enabled because the user has left keyguard. 776ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); 777ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 778ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // If there's a pending runnable because the user interacted with a widget 779ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // and we're leaving keyguard, then run it. 780ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch boolean deferKeyguardDone = false; 781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (mDismissAction != null) { 782ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch deferKeyguardDone = mDismissAction.onDismiss(); 783ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mDismissAction = null; 784ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 785ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (mViewMediatorCallback != null) { 786ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (deferKeyguardDone) { 787ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mViewMediatorCallback.keyguardDonePending(); 788ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mViewMediatorCallback.keyguardDone(true); 790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 792ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 793ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mViewStateManager.showBouncer(true); 794ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 795ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 796ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 797ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private OnClickHandler mOnClickHandler = new OnClickHandler() { 798ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 799ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public boolean onClickHandler(final View view, 800ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch final android.app.PendingIntent pendingIntent, 801ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch final Intent fillInIntent) { 802ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (pendingIntent.isActivity()) { 803ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch setOnDismissAction(new OnDismissAction() { 804ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public boolean onDismiss() { 805ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch try { 806ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT? 807ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Context context = view.getContext(); 808ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view, 809ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 0, 0, 810ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch view.getMeasuredWidth(), view.getMeasuredHeight()); 811ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch context.startIntentSender( 812ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pendingIntent.getIntentSender(), fillInIntent, 813ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Intent.FLAG_ACTIVITY_NEW_TASK, 814ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle()); 815ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } catch (IntentSender.SendIntentException e) { 816ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch android.util.Log.e(TAG, "Cannot send pending intent: ", e); 817ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } catch (Exception e) { 818ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch android.util.Log.e(TAG, "Cannot send pending intent due to " + 819ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch "unknown exception: ", e); 820ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 821ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 822ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 823ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }); 824ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 825ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (mViewStateManager.isChallengeShowing()) { 826ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mViewStateManager.showBouncer(true); 827ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 828ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mCallback.dismiss(false); 829ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 830ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 831ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 832ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return super.onClickHandler(view, pendingIntent, fillInIntent); 833ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 834ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 835ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 836ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 837ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Used to ignore callbacks from methods that are no longer current (e.g. face unlock). 838ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // This avoids unwanted asynchronous events from messing with the state. 839ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() { 840ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 841ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 842ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public void userActivity(long timeout) { 843ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 844ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 845ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 846ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public void showBackupSecurity() { 847ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 848ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 849ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 850ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public void setOnDismissAction(OnDismissAction action) { 851ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 852ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 853ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 854ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public void reportSuccessfulUnlockAttempt() { 855ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 856ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 857ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 858ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public void reportFailedUnlockAttempt() { 859ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 860ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 861ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 862ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public boolean isVerifyUnlockOnly() { 863ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 864ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 865ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 866ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch @Override 867ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public int getFailedAttempts() { 868 return 0; 869 } 870 871 @Override 872 public void dismiss(boolean securityVerified) { 873 } 874 }; 875 876 protected boolean mShowSecurityWhenReturn; 877 878 @Override 879 public void reset() { 880 mIsVerifyUnlockOnly = false; 881 mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_status_view)); 882 } 883 884 /** 885 * Sets an action to perform when keyguard is dismissed. 886 * @param action 887 */ 888 protected void setOnDismissAction(OnDismissAction action) { 889 mDismissAction = action; 890 } 891 892 private KeyguardSecurityView getSecurityView(SecurityMode securityMode) { 893 final int securityViewIdForMode = getSecurityViewIdForMode(securityMode); 894 KeyguardSecurityView view = null; 895 final int children = mSecurityViewContainer.getChildCount(); 896 for (int child = 0; child < children; child++) { 897 if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) { 898 view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child)); 899 break; 900 } 901 } 902 int layoutId = getLayoutIdFor(securityMode); 903 if (view == null && layoutId != 0) { 904 final LayoutInflater inflater = LayoutInflater.from(mContext); 905 if (DEBUG) Log.v(TAG, "inflating id = " + layoutId); 906 View v = inflater.inflate(layoutId, mSecurityViewContainer, false); 907 mSecurityViewContainer.addView(v); 908 updateSecurityView(v); 909 view = (KeyguardSecurityView)v; 910 } 911 912 if (view instanceof KeyguardSelectorView) { 913 KeyguardSelectorView selectorView = (KeyguardSelectorView) view; 914 View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container); 915 selectorView.setCarrierArea(carrierText); 916 } 917 918 return view; 919 } 920 921 /** 922 * Switches to the given security view unless it's already being shown, in which case 923 * this is a no-op. 924 * 925 * @param securityMode 926 */ 927 private void showSecurityScreen(SecurityMode securityMode) { 928 if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")"); 929 930 if (securityMode == mCurrentSecuritySelection) return; 931 932 KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection); 933 KeyguardSecurityView newView = getSecurityView(securityMode); 934 935 // Enter full screen mode if we're in SIM or Account screen 936 boolean fullScreenEnabled = getResources().getBoolean( 937 com.android.internal.R.bool.kg_sim_puk_account_full_screen); 938 boolean isSimOrAccount = securityMode == SecurityMode.SimPin 939 || securityMode == SecurityMode.SimPuk 940 || securityMode == SecurityMode.Account; 941 mAppWidgetContainer.setVisibility( 942 isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE); 943 944 if (mSlidingChallengeLayout != null) { 945 mSlidingChallengeLayout.setChallengeInteractive(!fullScreenEnabled); 946 } 947 948 // Emulate Activity life cycle 949 if (oldView != null) { 950 oldView.onPause(); 951 oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view 952 } 953 newView.onResume(KeyguardSecurityView.VIEW_REVEALED); 954 newView.setKeyguardCallback(mCallback); 955 956 final boolean needsInput = newView.needsInput(); 957 if (mViewMediatorCallback != null) { 958 mViewMediatorCallback.setNeedsInput(needsInput); 959 } 960 961 // Find and show this child. 962 final int childCount = mSecurityViewContainer.getChildCount(); 963 964 mSecurityViewContainer.setInAnimation( 965 AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_in)); 966 mSecurityViewContainer.setOutAnimation( 967 AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_out)); 968 final int securityViewIdForMode = getSecurityViewIdForMode(securityMode); 969 for (int i = 0; i < childCount; i++) { 970 if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) { 971 mSecurityViewContainer.setDisplayedChild(i); 972 break; 973 } 974 } 975 976 if (securityMode == SecurityMode.None) { 977 // Discard current runnable if we're switching back to the selector view 978 setOnDismissAction(null); 979 } 980 if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) { 981 // we're showing account as a backup, provide a way to get back to primary 982 setBackButtonEnabled(true); 983 } 984 mCurrentSecuritySelection = securityMode; 985 } 986 987 @Override 988 public void onScreenTurnedOn() { 989 if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); 990 showPrimarySecurityScreen(false); 991 getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON); 992 993 // This is a an attempt to fix bug 7137389 where the device comes back on but the entire 994 // layout is blank but forcing a layout causes it to reappear (e.g. with with 995 // hierarchyviewer). 996 requestLayout(); 997 998 if (mViewStateManager != null) { 999 mViewStateManager.showUsabilityHints(); 1000 } 1001 requestFocus(); 1002 } 1003 1004 @Override 1005 public void onScreenTurnedOff() { 1006 if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s", 1007 Integer.toHexString(hashCode()), SystemClock.uptimeMillis())); 1008 // Once the screen turns off, we no longer consider this to be first boot and we want the 1009 // biometric unlock to start next time keyguard is shown. 1010 KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); 1011 // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen 1012 // turns off we reset that behavior 1013 clearAppWidgetToShow(); 1014 checkAppWidgetConsistency(); 1015 showPrimarySecurityScreen(true); 1016 getSecurityView(mCurrentSecuritySelection).onPause(); 1017 CameraWidgetFrame cameraPage = findCameraPage(); 1018 if (cameraPage != null) { 1019 cameraPage.onScreenTurnedOff(); 1020 } 1021 clearFocus(); 1022 } 1023 1024 public void clearAppWidgetToShow() { 1025 mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID; 1026 } 1027 1028 @Override 1029 public void show() { 1030 if (DEBUG) Log.d(TAG, "show()"); 1031 showPrimarySecurityScreen(false); 1032 } 1033 1034 private boolean isSecure() { 1035 SecurityMode mode = mSecurityModel.getSecurityMode(); 1036 switch (mode) { 1037 case Pattern: 1038 return mLockPatternUtils.isLockPatternEnabled(); 1039 case Password: 1040 case PIN: 1041 return mLockPatternUtils.isLockPasswordEnabled(); 1042 case SimPin: 1043 case SimPuk: 1044 case Account: 1045 return true; 1046 case None: 1047 return false; 1048 default: 1049 throw new IllegalStateException("Unknown security mode " + mode); 1050 } 1051 } 1052 1053 @Override 1054 public void wakeWhenReadyTq(int keyCode) { 1055 if (DEBUG) Log.d(TAG, "onWakeKey"); 1056 if (keyCode == KeyEvent.KEYCODE_MENU && isSecure()) { 1057 if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU"); 1058 showSecurityScreen(SecurityMode.None); 1059 } else { 1060 if (DEBUG) Log.d(TAG, "poking wake lock immediately"); 1061 } 1062 if (mViewMediatorCallback != null) { 1063 mViewMediatorCallback.wakeUp(); 1064 } 1065 } 1066 1067 @Override 1068 public void verifyUnlock() { 1069 SecurityMode securityMode = mSecurityModel.getSecurityMode(); 1070 if (securityMode == KeyguardSecurityModel.SecurityMode.None) { 1071 if (mViewMediatorCallback != null) { 1072 mViewMediatorCallback.keyguardDone(true); 1073 } 1074 } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern 1075 && securityMode != KeyguardSecurityModel.SecurityMode.PIN 1076 && securityMode != KeyguardSecurityModel.SecurityMode.Password) { 1077 // can only verify unlock when in pattern/password mode 1078 if (mViewMediatorCallback != null) { 1079 mViewMediatorCallback.keyguardDone(false); 1080 } 1081 } else { 1082 // otherwise, go to the unlock screen, see if they can verify it 1083 mIsVerifyUnlockOnly = true; 1084 showSecurityScreen(securityMode); 1085 } 1086 } 1087 1088 private int getSecurityViewIdForMode(SecurityMode securityMode) { 1089 switch (securityMode) { 1090 case None: return R.id.keyguard_selector_view; 1091 case Pattern: return R.id.keyguard_pattern_view; 1092 case PIN: return R.id.keyguard_pin_view; 1093 case Password: return R.id.keyguard_password_view; 1094 case Biometric: return R.id.keyguard_face_unlock_view; 1095 case Account: return R.id.keyguard_account_view; 1096 case SimPin: return R.id.keyguard_sim_pin_view; 1097 case SimPuk: return R.id.keyguard_sim_puk_view; 1098 } 1099 return 0; 1100 } 1101 1102 private int getLayoutIdFor(SecurityMode securityMode) { 1103 switch (securityMode) { 1104 case None: return R.layout.keyguard_selector_view; 1105 case Pattern: return R.layout.keyguard_pattern_view; 1106 case PIN: return R.layout.keyguard_pin_view; 1107 case Password: return R.layout.keyguard_password_view; 1108 case Biometric: return R.layout.keyguard_face_unlock_view; 1109 case Account: return R.layout.keyguard_account_view; 1110 case SimPin: return R.layout.keyguard_sim_pin_view; 1111 case SimPuk: return R.layout.keyguard_sim_puk_view; 1112 default: 1113 return 0; 1114 } 1115 } 1116 1117 private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) { 1118 AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId); 1119 if (appWidgetInfo != null) { 1120 AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo); 1121 addWidget(view, pageIndex); 1122 return true; 1123 } else { 1124 if (updateDbIfFailed) { 1125 Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + " was null for user" 1126 + mUserId + ", deleting"); 1127 mAppWidgetHost.deleteAppWidgetId(appId); 1128 mLockPatternUtils.removeAppWidget(appId); 1129 } 1130 return false; 1131 } 1132 } 1133 1134 private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks = 1135 new CameraWidgetFrame.Callbacks() { 1136 @Override 1137 public void onLaunchingCamera() { 1138 setSliderHandleAlpha(0); 1139 } 1140 1141 @Override 1142 public void onCameraLaunchedSuccessfully() { 1143 if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) { 1144 mAppWidgetContainer.scrollLeft(); 1145 } 1146 setSliderHandleAlpha(1); 1147 mShowSecurityWhenReturn = true; 1148 } 1149 1150 @Override 1151 public void onCameraLaunchedUnsuccessfully() { 1152 setSliderHandleAlpha(1); 1153 } 1154 1155 private void setSliderHandleAlpha(float alpha) { 1156 SlidingChallengeLayout slider = 1157 (SlidingChallengeLayout) findViewById(R.id.sliding_layout); 1158 if (slider != null) { 1159 slider.setHandleAlpha(alpha); 1160 } 1161 } 1162 }; 1163 1164 private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() { 1165 @Override 1166 Context getContext() { 1167 return mContext; 1168 } 1169 1170 @Override 1171 KeyguardSecurityCallback getCallback() { 1172 return mCallback; 1173 } 1174 1175 @Override 1176 LockPatternUtils getLockPatternUtils() { 1177 return mLockPatternUtils; 1178 } 1179 }; 1180 1181 private int numWidgets() { 1182 final int childCount = mAppWidgetContainer.getChildCount(); 1183 int widgetCount = 0; 1184 for (int i = 0; i < childCount; i++) { 1185 if (mAppWidgetContainer.isWidgetPage(i)) { 1186 widgetCount++; 1187 } 1188 } 1189 return widgetCount; 1190 } 1191 1192 private void addDefaultWidgets() { 1193 if (!mSafeModeEnabled && !widgetsDisabledByDpm()) { 1194 LayoutInflater inflater = LayoutInflater.from(mContext); 1195 View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false); 1196 mAppWidgetContainer.addWidget(addWidget, 0); 1197 View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view); 1198 addWidgetButton.setOnClickListener(new OnClickListener() { 1199 @Override 1200 public void onClick(View v) { 1201 // Pass in an invalid widget id... the picker will allocate an ID for us 1202 mActivityLauncher.launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID); 1203 } 1204 }); 1205 } 1206 1207 // We currently disable cameras in safe mode because we support loading 3rd party 1208 // cameras we can't trust. TODO: plumb safe mode into camera creation code and only 1209 // inflate system-provided camera? 1210 if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted 1211 && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) { 1212 View cameraWidget = 1213 CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher); 1214 if (cameraWidget != null) { 1215 mAppWidgetContainer.addWidget(cameraWidget); 1216 } 1217 } 1218 1219 enableUserSelectorIfNecessary(); 1220 } 1221 1222 /** 1223 * Create KeyguardTransportControlView on demand. 1224 * @return 1225 */ 1226 private KeyguardTransportControlView getOrCreateTransportControl() { 1227 if (mTransportControl == null) { 1228 LayoutInflater inflater = LayoutInflater.from(mContext); 1229 mTransportControl = (KeyguardTransportControlView) 1230 inflater.inflate(R.layout.keyguard_transport_control_view, this, false); 1231 } 1232 return mTransportControl; 1233 } 1234 1235 private int getInsertPageIndex() { 1236 View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget); 1237 int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget); 1238 if (insertionIndex < 0) { 1239 insertionIndex = 0; // no add widget page found 1240 } else { 1241 insertionIndex++; // place after add widget 1242 } 1243 return insertionIndex; 1244 } 1245 1246 private void addDefaultStatusWidget(int index) { 1247 LayoutInflater inflater = LayoutInflater.from(mContext); 1248 View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true); 1249 mAppWidgetContainer.addWidget(statusWidget, index); 1250 } 1251 1252 private void addWidgetsFromSettings() { 1253 if (mSafeModeEnabled || widgetsDisabledByDpm()) { 1254 return; 1255 } 1256 1257 int insertionIndex = getInsertPageIndex(); 1258 1259 // Add user-selected widget 1260 final int[] widgets = mLockPatternUtils.getAppWidgets(); 1261 1262 if (widgets == null) { 1263 Log.d(TAG, "Problem reading widgets"); 1264 } else { 1265 for (int i = widgets.length -1; i >= 0; i--) { 1266 if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) { 1267 addDefaultStatusWidget(insertionIndex); 1268 } else { 1269 // We add the widgets from left to right, starting after the first page after 1270 // the add page. We count down, since the order will be persisted from right 1271 // to left, starting after camera. 1272 addWidget(widgets[i], insertionIndex, true); 1273 } 1274 } 1275 } 1276 } 1277 1278 private int allocateIdForDefaultAppWidget() { 1279 int appWidgetId; 1280 Resources res = getContext().getResources(); 1281 ComponentName defaultAppWidget = new ComponentName( 1282 res.getString(R.string.widget_default_package_name), 1283 res.getString(R.string.widget_default_class_name)); 1284 1285 // Note: we don't support configuring the widget 1286 appWidgetId = mAppWidgetHost.allocateAppWidgetId(); 1287 1288 try { 1289 mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget); 1290 1291 } catch (IllegalArgumentException e) { 1292 Log.e(TAG, "Error when trying to bind default AppWidget: " + e); 1293 mAppWidgetHost.deleteAppWidgetId(appWidgetId); 1294 appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; 1295 } 1296 return appWidgetId; 1297 } 1298 public void checkAppWidgetConsistency() { 1299 // Since this method may bind a widget (which we can't do until boot completed) we 1300 // may have to defer it until after boot complete. 1301 if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) { 1302 mCheckAppWidgetConsistencyOnBootCompleted = true; 1303 return; 1304 } 1305 final int childCount = mAppWidgetContainer.getChildCount(); 1306 boolean widgetPageExists = false; 1307 for (int i = 0; i < childCount; i++) { 1308 if (mAppWidgetContainer.isWidgetPage(i)) { 1309 widgetPageExists = true; 1310 break; 1311 } 1312 } 1313 if (!widgetPageExists) { 1314 final int insertPageIndex = getInsertPageIndex(); 1315 1316 final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm(); 1317 boolean addedDefaultAppWidget = false; 1318 1319 if (!mSafeModeEnabled) { 1320 if (userAddedWidgetsEnabled) { 1321 int appWidgetId = allocateIdForDefaultAppWidget(); 1322 if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { 1323 addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true); 1324 } 1325 } else { 1326 // note: even if widgetsDisabledByDpm() returns true, we still bind/create 1327 // the default appwidget if possible 1328 int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId(); 1329 if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { 1330 appWidgetId = allocateIdForDefaultAppWidget(); 1331 if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { 1332 mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId); 1333 } 1334 } 1335 if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { 1336 addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false); 1337 if (!addedDefaultAppWidget) { 1338 mAppWidgetHost.deleteAppWidgetId(appWidgetId); 1339 mLockPatternUtils.writeFallbackAppWidgetId( 1340 AppWidgetManager.INVALID_APPWIDGET_ID); 1341 } 1342 } 1343 } 1344 } 1345 1346 // Use the built-in status/clock view if we can't inflate the default widget 1347 if (!addedDefaultAppWidget) { 1348 addDefaultStatusWidget(insertPageIndex); 1349 } 1350 1351 // trigger DB updates only if user-added widgets are enabled 1352 if (!mSafeModeEnabled && userAddedWidgetsEnabled) { 1353 mAppWidgetContainer.onAddView( 1354 mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex); 1355 } 1356 } 1357 } 1358 1359 Runnable mSwitchPageRunnable = new Runnable() { 1360 @Override 1361 public void run() { 1362 showAppropriateWidgetPage(); 1363 } 1364 }; 1365 1366 static class SavedState extends BaseSavedState { 1367 int transportState; 1368 int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID; 1369 1370 SavedState(Parcelable superState) { 1371 super(superState); 1372 } 1373 1374 private SavedState(Parcel in) { 1375 super(in); 1376 this.transportState = in.readInt(); 1377 this.appWidgetToShow = in.readInt(); 1378 } 1379 1380 @Override 1381 public void writeToParcel(Parcel out, int flags) { 1382 super.writeToParcel(out, flags); 1383 out.writeInt(this.transportState); 1384 out.writeInt(this.appWidgetToShow); 1385 } 1386 1387 public static final Parcelable.Creator<SavedState> CREATOR 1388 = new Parcelable.Creator<SavedState>() { 1389 public SavedState createFromParcel(Parcel in) { 1390 return new SavedState(in); 1391 } 1392 1393 public SavedState[] newArray(int size) { 1394 return new SavedState[size]; 1395 } 1396 }; 1397 } 1398 1399 @Override 1400 public Parcelable onSaveInstanceState() { 1401 if (DEBUG) Log.d(TAG, "onSaveInstanceState, tstate=" + mTransportState); 1402 Parcelable superState = super.onSaveInstanceState(); 1403 SavedState ss = new SavedState(superState); 1404 // If the transport is showing, force it to show it on restore. 1405 final boolean showing = mTransportControl != null 1406 && mAppWidgetContainer.getWidgetPageIndex(mTransportControl) >= 0; 1407 ss.transportState = showing ? TRANSPORT_VISIBLE : mTransportState; 1408 ss.appWidgetToShow = mAppWidgetToShow; 1409 return ss; 1410 } 1411 1412 @Override 1413 public void onRestoreInstanceState(Parcelable state) { 1414 if (!(state instanceof SavedState)) { 1415 super.onRestoreInstanceState(state); 1416 return; 1417 } 1418 SavedState ss = (SavedState) state; 1419 super.onRestoreInstanceState(ss.getSuperState()); 1420 mTransportState = (ss.transportState); 1421 mAppWidgetToShow = ss.appWidgetToShow; 1422 if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState); 1423 post(mSwitchPageRunnable); 1424 } 1425 1426 @Override 1427 public void onWindowFocusChanged(boolean hasWindowFocus) { 1428 super.onWindowFocusChanged(hasWindowFocus); 1429 if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused")); 1430 if (hasWindowFocus && mShowSecurityWhenReturn) { 1431 SlidingChallengeLayout slider = 1432 (SlidingChallengeLayout) findViewById(R.id.sliding_layout); 1433 if (slider != null) { 1434 slider.setHandleAlpha(1); 1435 slider.showChallenge(true); 1436 } 1437 mShowSecurityWhenReturn = false; 1438 } 1439 } 1440 1441 private void showAppropriateWidgetPage() { 1442 int state = mTransportState; 1443 ensureTransportPresentOrRemoved(state); 1444 int pageToShow = getAppropriateWidgetPage(state); 1445 mAppWidgetContainer.setCurrentPage(pageToShow); 1446 } 1447 1448 /** 1449 * Examines the current state and adds the transport to the widget pager when the state changes. 1450 * 1451 * Showing the initial transport and keeping it around is a bit tricky because the signals 1452 * coming from music players aren't always clear. Here's how the states are handled: 1453 * 1454 * {@link TRANSPORT_GONE} means we have no reason to show the transport - remove it if present. 1455 * 1456 * {@link TRANSPORT_INVISIBLE} means we have potential to show the transport because a music 1457 * player is registered but not currently playing music (or we don't know the state yet). The 1458 * code adds it conditionally on play state. 1459 * 1460 * {@link #TRANSPORT_VISIBLE} means a music player is active and transport should be showing. 1461 * 1462 * Once the transport is showing, we always show it until keyguard is dismissed. This state is 1463 * maintained by onSave/RestoreInstanceState(). This state is cleared in 1464 * {@link KeyguardViewManager#hide} when keyguard is dismissed, which causes the transport to be 1465 * gone when keyguard is restarted until we get an update with the current state. 1466 * 1467 * @param state 1468 */ 1469 private void ensureTransportPresentOrRemoved(int state) { 1470 final boolean showing = getWidgetPosition(R.id.keyguard_transport_control) != -1; 1471 final boolean visible = state == TRANSPORT_VISIBLE; 1472 final boolean shouldBeVisible = state == TRANSPORT_INVISIBLE && isMusicPlaying(state); 1473 if (!showing && (visible || shouldBeVisible)) { 1474 if (DEBUGXPORT) Log.v(TAG, "add transport"); 1475 // insert to left of camera if it exists, otherwise after right-most widget 1476 int lastWidget = mAppWidgetContainer.getChildCount() - 1; 1477 int position = 0; // handle no widget case 1478 if (lastWidget >= 0) { 1479 position = mAppWidgetContainer.isCameraPage(lastWidget) ? 1480 lastWidget : lastWidget + 1; 1481 } 1482 mAppWidgetContainer.addWidget(getOrCreateTransportControl(), position); 1483 } else if (showing && state == TRANSPORT_GONE) { 1484 if (DEBUGXPORT) Log.v(TAG, "remove transport"); 1485 mAppWidgetContainer.removeWidget(getOrCreateTransportControl()); 1486 mTransportControl = null; 1487 } 1488 } 1489 1490 private CameraWidgetFrame findCameraPage() { 1491 for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) { 1492 if (mAppWidgetContainer.isCameraPage(i)) { 1493 return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i); 1494 } 1495 } 1496 return null; 1497 } 1498 1499 boolean isMusicPage(int pageIndex) { 1500 return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control); 1501 } 1502 1503 private int getAppropriateWidgetPage(int musicTransportState) { 1504 // assumes at least one widget (besides camera + add) 1505 if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) { 1506 final int childCount = mAppWidgetContainer.getChildCount(); 1507 for (int i = 0; i < childCount; i++) { 1508 if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId() 1509 == mAppWidgetToShow) { 1510 return i; 1511 } 1512 } 1513 mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID; 1514 } 1515 // if music playing, show transport 1516 if (musicTransportState == TRANSPORT_VISIBLE) { 1517 if (DEBUG) Log.d(TAG, "Music playing, show transport"); 1518 return mAppWidgetContainer.getWidgetPageIndex(getOrCreateTransportControl()); 1519 } 1520 1521 // else show the right-most widget (except for camera) 1522 int rightMost = mAppWidgetContainer.getChildCount() - 1; 1523 if (mAppWidgetContainer.isCameraPage(rightMost)) { 1524 rightMost--; 1525 } 1526 if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost); 1527 return rightMost; 1528 } 1529 1530 private void enableUserSelectorIfNecessary() { 1531 if (!UserManager.supportsMultipleUsers()) { 1532 return; // device doesn't support multi-user mode 1533 } 1534 final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1535 if (um == null) { 1536 Throwable t = new Throwable(); 1537 t.fillInStackTrace(); 1538 Log.e(TAG, "user service is null.", t); 1539 return; 1540 } 1541 1542 // if there are multiple users, we need to enable to multi-user switcher 1543 final List<UserInfo> users = um.getUsers(true); 1544 if (users == null) { 1545 Throwable t = new Throwable(); 1546 t.fillInStackTrace(); 1547 Log.e(TAG, "list of users is null.", t); 1548 return; 1549 } 1550 1551 final View multiUserView = findViewById(R.id.keyguard_user_selector); 1552 if (multiUserView == null) { 1553 Throwable t = new Throwable(); 1554 t.fillInStackTrace(); 1555 Log.e(TAG, "can't find user_selector in layout.", t); 1556 return; 1557 } 1558 1559 if (users.size() > 1) { 1560 if (multiUserView instanceof KeyguardMultiUserSelectorView) { 1561 mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView; 1562 mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE); 1563 mKeyguardMultiUserSelectorView.addUsers(users); 1564 UserSwitcherCallback callback = new UserSwitcherCallback() { 1565 @Override 1566 public void hideSecurityView(int duration) { 1567 mSecurityViewContainer.animate().alpha(0).setDuration(duration); 1568 } 1569 1570 @Override 1571 public void showSecurityView() { 1572 mSecurityViewContainer.setAlpha(1.0f); 1573 } 1574 1575 @Override 1576 public void showUnlockHint() { 1577 if (mKeyguardSelectorView != null) { 1578 mKeyguardSelectorView.showUsabilityHint(); 1579 } 1580 } 1581 1582 @Override 1583 public void userActivity() { 1584 if (mViewMediatorCallback != null) { 1585 mViewMediatorCallback.userActivity(); 1586 } 1587 } 1588 }; 1589 mKeyguardMultiUserSelectorView.setCallback(callback); 1590 } else { 1591 Throwable t = new Throwable(); 1592 t.fillInStackTrace(); 1593 if (multiUserView == null) { 1594 Log.e(TAG, "could not find the user_selector.", t); 1595 } else { 1596 Log.e(TAG, "user_selector is the wrong type.", t); 1597 } 1598 } 1599 } 1600 } 1601 1602 @Override 1603 public void cleanUp() { 1604 // Make sure we let go of all widgets and their package contexts promptly. If we don't do 1605 // this, and the associated application is uninstalled, it can cause a soft reboot. 1606 int count = mAppWidgetContainer.getChildCount(); 1607 for (int i = 0; i < count; i++) { 1608 KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i); 1609 frame.removeAllViews(); 1610 } 1611 } 1612 1613 /** 1614 * In general, we enable unlocking the insecure keyguard with the menu key. However, there are 1615 * some cases where we wish to disable it, notably when the menu button placement or technology 1616 * is prone to false positives. 1617 * 1618 * @return true if the menu key should be enabled 1619 */ 1620 private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key"; 1621 private boolean shouldEnableMenuKey() { 1622 final Resources res = getResources(); 1623 final boolean configDisabled = res.getBoolean( 1624 com.android.internal.R.bool.config_disableMenuKeyInLockScreen); 1625 final boolean isTestHarness = ActivityManager.isRunningInTestHarness(); 1626 final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); 1627 return !configDisabled || isTestHarness || fileOverride; 1628 } 1629 1630 public void goToUserSwitcher() { 1631 mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_multi_user_selector)); 1632 } 1633 1634 public void goToWidget(int appWidgetId) { 1635 mAppWidgetToShow = appWidgetId; 1636 mSwitchPageRunnable.run(); 1637 } 1638 1639 public boolean handleMenuKey() { 1640 // The following enables the MENU key to work for testing automation 1641 if (shouldEnableMenuKey()) { 1642 showNextSecurityScreenOrFinish(false); 1643 return true; 1644 } 1645 return false; 1646 } 1647 1648 public boolean handleBackKey() { 1649 if (mCurrentSecuritySelection == SecurityMode.Account) { 1650 // go back to primary screen and re-disable back 1651 setBackButtonEnabled(false); 1652 showPrimarySecurityScreen(false /*turningOff*/); 1653 return true; 1654 } 1655 if (mCurrentSecuritySelection != SecurityMode.None) { 1656 mCallback.dismiss(false); 1657 return true; 1658 } 1659 return false; 1660 } 1661 1662 /** 1663 * Dismisses the keyguard by going to the next screen or making it gone. 1664 */ 1665 public void dismiss() { 1666 showNextSecurityScreenOrFinish(false); 1667 } 1668 1669 public void showAssistant() { 1670 final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 1671 .getAssistIntent(mContext, true, UserHandle.USER_CURRENT); 1672 1673 if (intent == null) return; 1674 1675 final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, 1676 R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit, 1677 getHandler(), null); 1678 1679 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1680 1681 mActivityLauncher.launchActivityWithAnimation( 1682 intent, false, opts.toBundle(), null, null); 1683 } 1684} 1685