11f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/*
21f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
31f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
41f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
51f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * you may not use this file except in compliance with the License.
61f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * You may obtain a copy of the License at
71f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
81f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
91f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * See the License for the specific language governing permissions and
141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * limitations under the License.
151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpackage com.android.internal.policy.impl.keyguard;
181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
195dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackbornimport android.app.ActivityManagerNative;
205dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackbornimport android.app.IUserSwitchObserver;
21b030476d193a423f6c1baf3053f66fc768c925e0Jim Millerimport android.app.admin.DevicePolicyManager;
221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.BroadcastReceiver;
231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.IntentFilter;
261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.database.ContentObserver;
271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport static android.os.BatteryManager.BATTERY_STATUS_FULL;
281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
2916464b8e55020a4d77a8e5e4673db974e749dc82Jim Millerimport static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
3016464b8e55020a4d77a8e5e4673db974e749dc82Jim Millerimport static android.os.BatteryManager.EXTRA_STATUS;
3116464b8e55020a4d77a8e5e4673db974e749dc82Jim Millerimport static android.os.BatteryManager.EXTRA_PLUGGED;
3216464b8e55020a4d77a8e5e4673db974e749dc82Jim Millerimport static android.os.BatteryManager.EXTRA_LEVEL;
3316464b8e55020a4d77a8e5e4673db974e749dc82Jim Millerimport static android.os.BatteryManager.EXTRA_HEALTH;
3447088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Millerimport android.media.AudioManager;
3579a444a0cd78bc6528e19336a0d49ef4a17b263cJim Millerimport android.os.BatteryManager;
361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Handler;
375dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackbornimport android.os.IRemoteCallback;
381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Message;
395dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackbornimport android.os.RemoteException;
401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.provider.Settings;
41a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville
42a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Savilleimport com.android.internal.telephony.IccCardConstants;
431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.telephony.TelephonyIntents;
44c23024d32779b170dde32a50fbdd945ce521b874Jim Miller
45c23024d32779b170dde32a50fbdd945ce521b874Jim Millerimport android.telephony.TelephonyManager;
461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.R;
481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.google.android.collect.Lists;
491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
50dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport java.lang.ref.WeakReference;
511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.ArrayList;
521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Watches for updates that may be interesting to the keyguard, and provides
551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * the up to date information as well as a registration for callbacks that care
561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * to be updated.
571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Note: under time crunch, this has been extended to include some stuff that
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * doesn't really belong here.  see {@link #handleBatteryUpdate} where it shutdowns
60258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
61258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller * and {@link #clearFailedUnlockAttempts()}.  Maybe we should rename this 'KeyguardContext'...
621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectpublic class KeyguardUpdateMonitor {
641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
65bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final String TAG = "KeyguardUpdateMonitor";
66bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final boolean DEBUG = false;
67bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final boolean DEBUG_SIM_STATES = DEBUG || false;
68bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
69bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int LOW_BATTERY_THRESHOLD = 20;
701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
71bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    // Callback messages
72bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_TIME_UPDATE = 301;
73bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_BATTERY_UPDATE = 302;
74bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_CARRIER_INFO_UPDATE = 303;
75bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_SIM_STATE_CHANGE = 304;
76bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_RINGER_MODE_CHANGED = 305;
77bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_PHONE_STATE_CHANGED = 306;
78bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
79bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_DEVICE_PROVISIONED = 308;
805737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private static final int MSG_DPM_STATE_CHANGED = 309;
815737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private static final int MSG_USER_SWITCHED = 310;
825737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private static final int MSG_USER_REMOVED = 311;
83f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett    private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
84efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    protected static final int MSG_BOOT_COMPLETED = 313;
85efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
87dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private static KeyguardUpdateMonitor sInstance;
88dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final Context mContext;
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
91bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    // Telephony state
92a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville    private IccCardConstants.State mSimState = IccCardConstants.State.READY;
93bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private CharSequence mTelephonyPlmn;
94bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private CharSequence mTelephonySpn;
95bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private int mRingMode;
96bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private int mPhoneState;
975d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett    private boolean mKeyguardIsVisible;
984eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    private boolean mBootCompleted;
991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Device provisioning state
1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mDeviceProvisioned;
10247088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Battery status
10416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller    private BatteryStatus mBatteryStatus;
10579a444a0cd78bc6528e19336a0d49ef4a17b263cJim Miller
106dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Password attempts
1071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private int mFailedAttempts = 0;
108ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna    private int mFailedBiometricUnlockAttempts = 0;
1091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1100ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    private boolean mAlternateUnlockEnabled;
111cc4104fd71225ed092f16b11882d9a10084e34acBrian Colonna
112054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    private boolean mClockVisible;
113054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
1146212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
115dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mCallbacks = Lists.newArrayList();
1161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ContentObserver mContentObserver;
1171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
118bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private final Handler mHandler = new Handler() {
119bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        @Override
120bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public void handleMessage(Message msg) {
121bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            switch (msg.what) {
122bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_TIME_UPDATE:
123bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleTimeUpdate();
124bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
125bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_BATTERY_UPDATE:
126bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleBatteryUpdate((BatteryStatus) msg.obj);
127bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
128bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_CARRIER_INFO_UPDATE:
129bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleCarrierInfoUpdate();
130bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
131bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_SIM_STATE_CHANGE:
132bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleSimStateChange((SimArgs) msg.obj);
133bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
134bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_RINGER_MODE_CHANGED:
135bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleRingerModeChange(msg.arg1);
136bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
137bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_PHONE_STATE_CHANGED:
138bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handlePhoneStateChanged((String)msg.obj);
139bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
140bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_CLOCK_VISIBILITY_CHANGED:
141bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleClockVisibilityChanged();
142bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
143bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_DEVICE_PROVISIONED:
144bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleDeviceProvisioned();
145bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
146bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_DPM_STATE_CHANGED:
147bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleDevicePolicyManagerStateChanged();
148bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
149bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_USER_SWITCHED:
1505dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                    handleUserSwitched(msg.arg1, (IRemoteCallback)msg.obj);
151bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
152bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_USER_REMOVED:
153bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleUserRemoved(msg.arg1);
154bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
155f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett                case MSG_KEYGUARD_VISIBILITY_CHANGED:
156f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett                    handleKeyguardVisibilityChanged(msg.arg1);
157f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett                    break;
158efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                case MSG_BOOT_COMPLETED:
159efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                    handleBootCompleted();
160efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                    break;
161f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett
162bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            }
163bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
164bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    };
165bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
166bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
167bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
168bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public void onReceive(Context context, Intent intent) {
169bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            final String action = intent.getAction();
170bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            if (DEBUG) Log.d(TAG, "received broadcast " + action);
171bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
172bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            if (Intent.ACTION_TIME_TICK.equals(action)
173bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    || Intent.ACTION_TIME_CHANGED.equals(action)
174bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
175bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE));
176bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
177bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mTelephonyPlmn = getTelephonyPlmnFrom(intent);
178bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mTelephonySpn = getTelephonySpnFrom(intent);
179bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
180bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
181bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
182bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
183bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
184bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
185bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final Message msg = mHandler.obtainMessage(
186bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                        MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
187bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(msg);
188bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
189bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                if (DEBUG_SIM_STATES) {
190bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    Log.v(TAG, "action " + action + " state" +
191bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                        intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
192bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                }
193bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(
194bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                        MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
195bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
196bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
197bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                        intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
198bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
199bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
200bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
201bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
202bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    .equals(action)) {
203bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED));
204bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
205bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
206dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                       intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
207efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
208efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                mHandler.sendMessage(mHandler.obtainMessage(MSG_BOOT_COMPLETED));
209bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            }
210bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
211bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    };
2122de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller
2131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
21447088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller     * When we receive a
21547088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller     * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
21637c124c3fa3078af98c0ebd3e52c9a4ca477a767Wink Saville     * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
2171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * we need a single object to pass to the handler.  This class helps decode
21847088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller     * the intent and provide a {@link SimCard.State} result.
2191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static class SimArgs {
221a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        public final IccCardConstants.State simState;
2221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
223a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        SimArgs(IccCardConstants.State state) {
22490d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller            simState = state;
22590d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller        }
22690d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller
22790d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller        static SimArgs fromIntent(Intent intent) {
228a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            IccCardConstants.State state;
2291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
2301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
2311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
232a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
233a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
234b0b24b3df50988d23f571b83d829fecc986ec497John Wang                final String absentReason = intent
235a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
236b0b24b3df50988d23f571b83d829fecc986ec497John Wang
237a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
238b0b24b3df50988d23f571b83d829fecc986ec497John Wang                        absentReason)) {
239a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.PERM_DISABLED;
240b0b24b3df50988d23f571b83d829fecc986ec497John Wang                } else {
241a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.ABSENT;
242b0b24b3df50988d23f571b83d829fecc986ec497John Wang                }
243a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
244a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                state = IccCardConstants.State.READY;
245a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
2461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final String lockedReason = intent
247a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                        .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
248a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
249a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.PIN_REQUIRED;
250a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
251a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.PUK_REQUIRED;
2521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                } else {
253a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.UNKNOWN;
2541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
255a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
256a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                state = IccCardConstants.State.NETWORK_LOCKED;
257109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller            } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
258109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                        || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
259109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                // This is required because telephony doesn't return to "READY" after
260109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                // these state transitions. See bug 7197471.
261109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                state = IccCardConstants.State.READY;
2621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            } else {
263a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                state = IccCardConstants.State.UNKNOWN;
2641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
26590d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller            return new SimArgs(state);
2661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public String toString() {
2691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return simState.toString();
2701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
273bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /* package */ static class BatteryStatus {
27416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int status;
27516464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int level;
27616464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int plugged;
27716464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int health;
27816464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public BatteryStatus(int status, int level, int plugged, int health) {
27916464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.status = status;
28016464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.level = level;
28116464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.plugged = plugged;
28216464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.health = health;
28316464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        }
28416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller
285bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        /**
286a92a01bb0bb458401af90bed5a46d932278160d7Brian Muramatsu         * Determine whether the device is plugged in (USB, power, or wireless).
287bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * @return true if the device is plugged in.
288bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         */
289bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        boolean isPluggedIn() {
290bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            return plugged == BatteryManager.BATTERY_PLUGGED_AC
291a92a01bb0bb458401af90bed5a46d932278160d7Brian Muramatsu                    || plugged == BatteryManager.BATTERY_PLUGGED_USB
292a92a01bb0bb458401af90bed5a46d932278160d7Brian Muramatsu                    || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
293bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
294bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
295bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        /**
296bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * Whether or not the device is charged. Note that some devices never return 100% for
297bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * battery level, so this allows either battery level or status to determine if the
298bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * battery is charged.
299bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * @return true if the device is charged
300bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         */
301bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public boolean isCharged() {
302bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            return status == BATTERY_STATUS_FULL || level >= 100;
303bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
304bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
305bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        /**
306bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * Whether battery is low and needs to be charged.
307bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * @return true if battery is low
308bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         */
309bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public boolean isBatteryLow() {
310bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            return level < LOW_BATTERY_THRESHOLD;
311bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
312bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
31316464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller    }
31416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller
315dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public static KeyguardUpdateMonitor getInstance(Context context) {
316dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (sInstance == null) {
317dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            sInstance = new KeyguardUpdateMonitor(context);
318dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
319dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return sInstance;
320dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
321dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
322dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardUpdateMonitor(Context context) {
3231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mContext = context;
32447088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
325bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown        mDeviceProvisioned = Settings.Global.getInt(
326bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
32747088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
3281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // Since device can't be un-provisioned, we only need to register a content observer
3291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // to update mDeviceProvisioned when we are...
3301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (!mDeviceProvisioned) {
331bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            watchForDeviceProvisioning();
3321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
33347088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
334bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // Take a guess at initial SIM state, battery status and PLMN until we get an update
335bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        mSimState = IccCardConstants.State.NOT_READY;
33616464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
3371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mTelephonyPlmn = getDefaultPlmn();
3381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
339bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // Watch for interesting updates
3401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final IntentFilter filter = new IntentFilter();
3411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_TIME_TICK);
3421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_TIME_CHANGED);
3431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
3441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
3451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
346c23024d32779b170dde32a50fbdd945ce521b874Jim Miller        filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
347a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
34847088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
349b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
35052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        filter.addAction(Intent.ACTION_USER_REMOVED);
351bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        context.registerReceiver(mBroadcastReceiver, filter);
3525dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn
353c276e82dd070e75017192507df33958a10cadb87Adam Cohen        final IntentFilter bootCompleteFilter = new IntentFilter();
354c276e82dd070e75017192507df33958a10cadb87Adam Cohen        bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
355c276e82dd070e75017192507df33958a10cadb87Adam Cohen        bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
356c276e82dd070e75017192507df33958a10cadb87Adam Cohen        context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
357c276e82dd070e75017192507df33958a10cadb87Adam Cohen
3585dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        try {
3595dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn            ActivityManagerNative.getDefault().registerUserSwitchObserver(
3605dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                    new IUserSwitchObserver.Stub() {
3615dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        @Override
3625dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        public void onUserSwitching(int newUserId, IRemoteCallback reply) {
3635dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED,
3645dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                                    newUserId, 0, reply));
3655dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        }
3665dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        @Override
3675dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        public void onUserSwitchComplete(int newUserId) throws RemoteException {
3685dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        }
3695dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                    });
3705dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        } catch (RemoteException e) {
3715dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn            // TODO Auto-generated catch block
3725dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn            e.printStackTrace();
3735dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        }
374bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    }
375bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
376bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private void watchForDeviceProvisioning() {
377bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        mContentObserver = new ContentObserver(mHandler) {
378bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            @Override
379bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            public void onChange(boolean selfChange) {
380bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                super.onChange(selfChange);
381bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                mDeviceProvisioned = Settings.Global.getInt(mContext.getContentResolver(),
382bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                    Settings.Global.DEVICE_PROVISIONED, 0) != 0;
383bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                if (mDeviceProvisioned) {
384bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
3851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
386bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
387bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            }
388bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        };
389bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
390bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        mContext.getContentResolver().registerContentObserver(
391bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
392bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                false, mContentObserver);
393bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
394bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // prevent a race condition between where we check the flag and where we register the
395bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // observer by grabbing the value once again...
396bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown        boolean provisioned = Settings.Global.getInt(mContext.getContentResolver(),
397bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown            Settings.Global.DEVICE_PROVISIONED, 0) != 0;
398bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        if (provisioned != mDeviceProvisioned) {
399bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            mDeviceProvisioned = provisioned;
400bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            if (mDeviceProvisioned) {
401bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
4021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
403bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
4041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
406bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
407bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_DPM_STATE_CHANGED}
408bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
409b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    protected void handleDevicePolicyManagerStateChanged() {
410dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
411dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
412dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
413dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onDevicePolicyManagerStateChanged();
414dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
415b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
416b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    }
417b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
418bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
419bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_USER_SWITCHED}
420bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
4215dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn    protected void handleUserSwitched(int userId, IRemoteCallback reply) {
422bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
423dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
424dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
425dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onUserSwitched(userId);
426dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
42752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        }
4280ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        setAlternateUnlockEnabled(false);
4295dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        try {
4305dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn            reply.sendResult(null);
4315dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        } catch (RemoteException e) {
4325dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        }
43352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
43452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
435bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
436efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen     * Handle {@link #MSG_BOOT_COMPLETED}
437efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen     */
438efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    protected void handleBootCompleted() {
4394eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen        mBootCompleted = true;
440efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        for (int i = 0; i < mCallbacks.size(); i++) {
441efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
442efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            if (cb != null) {
443efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                cb.onBootCompleted();
444efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            }
445efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        }
446efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    }
447efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen
448efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    /**
4494eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen     * We need to store this state in the KeyguardUpdateMonitor since this class will not be
4504eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen     * destroyed.
4514eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen     */
4524eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    public boolean hasBootCompleted() {
4534eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen        return mBootCompleted;
4544eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    }
4554eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen
4564eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    /**
457bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_USER_SWITCHED}
458bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
459bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    protected void handleUserRemoved(int userId) {
460bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
461dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
462dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
463dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onUserRemoved(userId);
464dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
465bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
466bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    }
467bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
468bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
469bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_DEVICE_PROVISIONED}
470bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
47124d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly    protected void handleDeviceProvisioned() {
472bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
473dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
474dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
475dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onDeviceProvisioned();
476dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
47724d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly        }
47824d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly        if (mContentObserver != null) {
47924d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly            // We don't need the observer anymore...
48024d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly            mContext.getContentResolver().unregisterContentObserver(mContentObserver);
48124d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly            mContentObserver = null;
48224d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly        }
48324d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly    }
48424d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly
485bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
486bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_PHONE_STATE_CHANGED}
487bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
488c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    protected void handlePhoneStateChanged(String newState) {
489c23024d32779b170dde32a50fbdd945ce521b874Jim Miller        if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
4903f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
4913f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller            mPhoneState = TelephonyManager.CALL_STATE_IDLE;
4923f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
4933f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller            mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
4943f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
4953f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller            mPhoneState = TelephonyManager.CALL_STATE_RINGING;
4963f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        }
497bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
498dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
499dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
500dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onPhoneStateChanged(mPhoneState);
501dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
502c23024d32779b170dde32a50fbdd945ce521b874Jim Miller        }
503c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    }
504c23024d32779b170dde32a50fbdd945ce521b874Jim Miller
505bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
506bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_RINGER_MODE_CHANGED}
507bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
50847088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller    protected void handleRingerModeChange(int mode) {
50947088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller        if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
5103f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        mRingMode = mode;
511bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
512dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
513dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
514dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onRingerModeChanged(mode);
515dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
51647088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller        }
51747088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller    }
51847088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
5191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
5201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Handle {@link #MSG_TIME_UPDATE}
5211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
5221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void handleTimeUpdate() {
5231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) Log.d(TAG, "handleTimeUpdate");
524bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
525dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
526dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
527dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onTimeChanged();
528dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
5291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
5331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Handle {@link #MSG_BATTERY_UPDATE}
5341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
535bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private void handleBatteryUpdate(BatteryStatus status) {
5361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
537bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
538bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        mBatteryStatus = status;
53916464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        if (batteryUpdateInteresting) {
540bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            for (int i = 0; i < mCallbacks.size(); i++) {
541dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
542dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                if (cb != null) {
543dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    cb.onRefreshBatteryInfo(status);
544dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                }
5451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
5501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Handle {@link #MSG_CARRIER_INFO_UPDATE}
5511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
5521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void handleCarrierInfoUpdate() {
5531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) Log.d(TAG, "handleCarrierInfoUpdate: plmn = " + mTelephonyPlmn
5541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            + ", spn = " + mTelephonySpn);
5551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
556bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
557dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
558dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
559dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
560dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
5611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
5651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Handle {@link #MSG_SIM_STATE_CHANGE}
5661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
5671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void handleSimStateChange(SimArgs simArgs) {
568a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        final IccCardConstants.State state = simArgs.simState;
5691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) {
5711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
5721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + "state resolved to " + state.toString());
5731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
575a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
5761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mSimState = state;
577bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            for (int i = 0; i < mCallbacks.size(); i++) {
578dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
579dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                if (cb != null) {
580dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    cb.onSimStateChanged(state);
581dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                }
5821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
586bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
587bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
588bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
589054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    private void handleClockVisibilityChanged() {
590054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey        if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
591bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
592dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
593dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
594dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onClockVisibilityChanged();
595dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
596054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey        }
597054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    }
598054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
599f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett    /**
600f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett     * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
601f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett     */
602f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett    private void handleKeyguardVisibilityChanged(int showing) {
603f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
6045d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett        boolean isShowing = (showing == 1);
6055d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett        mKeyguardIsVisible = isShowing;
606f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        for (int i = 0; i < mCallbacks.size(); i++) {
607f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
608f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett            if (cb != null) {
6095d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett                cb.onKeyguardVisibilityChanged(isShowing);
610f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett            }
611f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        }
612f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett    }
613f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett
6145d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett    public boolean isKeyguardVisible() {
6155d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett        return mKeyguardIsVisible;
6165d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett    }
6175d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett
61816464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller    private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
619bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        final boolean nowPluggedIn = current.isPluggedIn();
620bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        final boolean wasPluggedIn = old.isPluggedIn();
62179a444a0cd78bc6528e19336a0d49ef4a17b263cJim Miller        final boolean stateChangedWhilePluggedIn =
62216464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            wasPluggedIn == true && nowPluggedIn == true
62316464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            && (old.status != current.status);
62416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller
62516464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        // change in plug state is always interesting
62616464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
6271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
6281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // change in battery level while plugged in
63116464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        if (nowPluggedIn && old.level != current.level) {
6321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
6331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
63516464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        // change where battery needs charging
636bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
63716464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            return true;
6381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return false;
6401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
643a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville     * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
6441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return The string to use for the plmn, or null if it should not be shown.
6451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
6461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private CharSequence getTelephonyPlmnFrom(Intent intent) {
647a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
648a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN);
649bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            return (plmn != null) ? plmn : getDefaultPlmn();
6501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return null;
6521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
6551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return The default plmn (no service)
6561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
6571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private CharSequence getDefaultPlmn() {
658bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        return mContext.getResources().getText(R.string.lockscreen_carrier_default);
6591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
6621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
6631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return The string to use for the plmn, or null if it should not be shown.
6641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
6651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private CharSequence getTelephonySpnFrom(Intent intent) {
666a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
667a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN);
6681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (spn != null) {
6691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return spn;
6701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
6711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return null;
6731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
676bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Remove the given observer's callback.
677bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     *
6786212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller     * @param callback The callback to remove
6791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
6806212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    public void removeCallback(KeyguardUpdateMonitorCallback callback) {
6816212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
6826212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
6836212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller            if (mCallbacks.get(i).get() == callback) {
6846212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                mCallbacks.remove(i);
6856212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller            }
6866212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        }
6871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
6901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Register to receive notifications about general keyguard information
6911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * (see {@link InfoCallback}.
6926212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller     * @param callback The callback to register
6931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
694bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    public void registerCallback(KeyguardUpdateMonitorCallback callback) {
6956212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
6966212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        // Prevent adding duplicate callbacks
6976212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
6986212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller            if (mCallbacks.get(i).get() == callback) {
6996212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                if (DEBUG) Log.e(TAG, "Object tried to add another callback",
7006212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                        new Exception("Called by"));
7016212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                return;
702dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
703dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
7046212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
7056212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        removeCallback(null); // remove unused references
7066212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        sendUpdates(callback);
7076212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    }
7086212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller
7096212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
7106212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        // Notify listener of the current state
7116212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onRefreshBatteryInfo(mBatteryStatus);
7126212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onTimeChanged();
7136212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onRingerModeChanged(mRingMode);
7146212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onPhoneStateChanged(mPhoneState);
7156212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
7166212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onClockVisibilityChanged();
7176212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onSimStateChanged(mSimState);
7181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
720f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett    public void sendKeyguardVisibilityChanged(boolean showing) {
721f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
722f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
723f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        message.arg1 = showing ? 1 : 0;
724f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        message.sendToTarget();
725f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett    }
726f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett
727054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    public void reportClockVisible(boolean visible) {
728054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey        mClockVisible = visible;
729054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey        mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
730054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    }
731054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
732a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville    public IccCardConstants.State getSimState() {
7331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mSimState;
7341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
73790d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
7381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * have the information earlier than waiting for the intent
7391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * broadcast from the telephony code.
74090d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     *
74190d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
74290d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     * through mHandler, this *must* be called from the UI thread.
7431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
7440f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang    public void reportSimUnlocked() {
745a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville        handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
7461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public CharSequence getTelephonyPlmn() {
7491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mTelephonyPlmn;
7501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public CharSequence getTelephonySpn() {
7531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mTelephonySpn;
7541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
7571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return Whether the device is provisioned (whether they have gone through
7581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   the setup wizard)
7591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
7601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public boolean isDeviceProvisioned() {
7611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mDeviceProvisioned;
7621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
764258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    public int getFailedUnlockAttempts() {
7651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mFailedAttempts;
7661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
768258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    public void clearFailedUnlockAttempts() {
7691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mFailedAttempts = 0;
770ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna        mFailedBiometricUnlockAttempts = 0;
7711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
773258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    public void reportFailedUnlockAttempt() {
7741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mFailedAttempts++;
7751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7761c18828d20807342d37000746b18a3c1696f3b2eJim Miller
777054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    public boolean isClockVisible() {
778054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey        return mClockVisible;
779054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    }
780054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
781267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna    public int getPhoneState() {
782267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        return mPhoneState;
783267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna    }
784b9430d2a1c8dbf7b9998d349544c9ae133dab18fSteven Ross
785ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna    public void reportFailedBiometricUnlockAttempt() {
786ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna        mFailedBiometricUnlockAttempts++;
787b9430d2a1c8dbf7b9998d349544c9ae133dab18fSteven Ross    }
788b9430d2a1c8dbf7b9998d349544c9ae133dab18fSteven Ross
789ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna    public boolean getMaxBiometricUnlockAttemptsReached() {
790ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna        return mFailedBiometricUnlockAttempts >= FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
791b9430d2a1c8dbf7b9998d349544c9ae133dab18fSteven Ross    }
792b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
7930ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    public boolean isAlternateUnlockEnabled() {
7940ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        return mAlternateUnlockEnabled;
795cc4104fd71225ed092f16b11882d9a10084e34acBrian Colonna    }
796cc4104fd71225ed092f16b11882d9a10084e34acBrian Colonna
7970ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    public void setAlternateUnlockEnabled(boolean enabled) {
7980ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        mAlternateUnlockEnabled = enabled;
799cc4104fd71225ed092f16b11882d9a10084e34acBrian Colonna    }
800cc4104fd71225ed092f16b11882d9a10084e34acBrian Colonna
801b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    public boolean isSimLocked() {
802dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return isSimLocked(mSimState);
803dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
804dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
805dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public static boolean isSimLocked(IccCardConstants.State state) {
806dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return state == IccCardConstants.State.PIN_REQUIRED
807dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        || state == IccCardConstants.State.PUK_REQUIRED
808dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        || state == IccCardConstants.State.PERM_DISABLED;
809dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
810dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
811dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public boolean isSimPinSecure() {
812dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return isSimPinSecure(mSimState);
813dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
814dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
815dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public static boolean isSimPinSecure(IccCardConstants.State state) {
816dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        final IccCardConstants.State simState = state;
817dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return (simState == IccCardConstants.State.PIN_REQUIRED
818dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                || simState == IccCardConstants.State.PUK_REQUIRED
819dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                || simState == IccCardConstants.State.PERM_DISABLED);
820b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    }
8211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
822