Merge "Add multi-sim support to keyguard" into lmp-mr1-dev
This commit is contained in:
@ -240,12 +240,16 @@
|
||||
<string name="kg_pattern_instructions">Draw your pattern</string>
|
||||
<!-- Instructions for using the SIM PIN unlock screen -->
|
||||
<string name="kg_sim_pin_instructions">Enter SIM PIN</string>
|
||||
<!-- Instructions for using the SIM PIN unlock screen when there's more than one SIM -->
|
||||
<string name="kg_sim_pin_instructions_multi">Enter SIM PIN for \"<xliff:g id="carrier" example="CARD 1">%1$s</xliff:g>\"</string>
|
||||
<!-- Instructions for using the PIN unlock screen -->
|
||||
<string name="kg_pin_instructions">Enter PIN</string>
|
||||
<!-- Instructions for using the password unlock screen -->
|
||||
<string name="kg_password_instructions">Enter Password</string>
|
||||
<!-- Hint shown in the PUK screen that asks the user to enter the PUK code given to them by their provider -->
|
||||
<string name="kg_puk_enter_puk_hint">SIM is now disabled. Enter PUK code to continue. Contact carrier for details.</string>
|
||||
<!-- Hint shown when there are multiple SIMs in the device to ask the user to enter the PUK code given to them by their provider -->
|
||||
<string name="kg_puk_enter_puk_hint_multi">SIM \"<xliff:g id="carrier" example="CARD 1">%1$s</xliff:g>\" is now disabled. Enter PUK code to continue. Contact carrier for details.</string>
|
||||
<!-- Hint shown in the PUK unlock screen PIN TextView -->
|
||||
<string name="kg_puk_enter_pin_hint">Enter desired PIN code</string>
|
||||
<!-- Message shown when the user needs to confirm the PIN they just entered in the PUK screen -->
|
||||
|
@ -48,7 +48,7 @@ public class CarrierText extends TextView {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSimStateChanged(IccCardConstants.State simState) {
|
||||
public void onSimStateChanged(int subId, int slotId, State simState) {
|
||||
mSimState = simState;
|
||||
updateCarrierText(mSimState, mPlmn, mSpn);
|
||||
}
|
||||
|
@ -36,22 +36,18 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
* allows the user to return to the call.
|
||||
*/
|
||||
public class EmergencyButton extends Button {
|
||||
|
||||
private static final int EMERGENCY_CALL_TIMEOUT = 10000; // screen timeout after starting e.d.
|
||||
private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
|
||||
|
||||
KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
|
||||
|
||||
@Override
|
||||
public void onSimStateChanged(State simState) {
|
||||
int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
|
||||
updateEmergencyCallButton(simState, phoneState);
|
||||
public void onSimStateChanged(int subId, int slotId, State simState) {
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPhoneStateChanged(int phoneState) {
|
||||
State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
|
||||
updateEmergencyCallButton(simState, phoneState);
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
};
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
@ -87,9 +83,7 @@ public class EmergencyButton extends Button {
|
||||
takeEmergencyCallAction();
|
||||
}
|
||||
});
|
||||
int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
|
||||
State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
|
||||
updateEmergencyCallButton(simState, phoneState);
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,12 +106,12 @@ public class EmergencyButton extends Button {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEmergencyCallButton(State simState, int phoneState) {
|
||||
private void updateEmergencyCallButton() {
|
||||
boolean enabled = false;
|
||||
if (mLockPatternUtils.isInCall()) {
|
||||
enabled = true; // always show "return to call" if phone is off-hook
|
||||
} else if (mLockPatternUtils.isEmergencyCallCapable()) {
|
||||
boolean simLocked = KeyguardUpdateMonitor.getInstance(mContext).isSimLocked();
|
||||
final boolean simLocked = KeyguardUpdateMonitor.getInstance(mContext).isSimPinVoiceSecure();
|
||||
if (simLocked) {
|
||||
// Some countries can't handle emergency calls while SIM is locked.
|
||||
enabled = mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked();
|
||||
|
@ -25,5 +25,6 @@ public class KeyguardConstants {
|
||||
* Turns on debugging information for the whole Keyguard. This is very verbose and should only
|
||||
* be used temporarily for debugging.
|
||||
*/
|
||||
public static final boolean DEBUG = false;
|
||||
public static final boolean DEBUG = true;
|
||||
public static final boolean DEBUG_SIM_STATES = true;
|
||||
}
|
||||
|
@ -17,11 +17,15 @@ package com.android.keyguard;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class KeyguardSecurityModel {
|
||||
|
||||
/**
|
||||
@ -75,12 +79,13 @@ public class KeyguardSecurityModel {
|
||||
}
|
||||
|
||||
SecurityMode getSecurityMode() {
|
||||
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
|
||||
final IccCardConstants.State simState = updateMonitor.getSimState();
|
||||
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
|
||||
SecurityMode mode = SecurityMode.None;
|
||||
if (simState == IccCardConstants.State.PIN_REQUIRED) {
|
||||
if (monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED)
|
||||
!= SubscriptionManager.INVALID_SUB_ID) {
|
||||
mode = SecurityMode.SimPin;
|
||||
} else if (simState == IccCardConstants.State.PUK_REQUIRED
|
||||
} else if (monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED)
|
||||
!= SubscriptionManager.INVALID_SUB_ID
|
||||
&& mLockPatternUtils.isPukUnlockScreenEnable()) {
|
||||
mode = SecurityMode.SimPuk;
|
||||
} else {
|
||||
|
@ -17,15 +17,21 @@
|
||||
package com.android.keyguard;
|
||||
|
||||
import com.android.internal.telephony.ITelephony;
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.IccCardConstants.State;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
@ -35,13 +41,22 @@ import android.view.WindowManager;
|
||||
*/
|
||||
public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
private static final String LOG_TAG = "KeyguardSimPinView";
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG_SIM_STATES;
|
||||
public static final String TAG = "KeyguardSimPinView";
|
||||
|
||||
private ProgressDialog mSimUnlockProgressDialog = null;
|
||||
private CheckSimPin mCheckSimPinThread;
|
||||
|
||||
private AlertDialog mRemainingAttemptsDialog;
|
||||
private int mSubId;
|
||||
|
||||
KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onSimStateChanged(int subId, int slotId, State simState) {
|
||||
if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
|
||||
resetState();
|
||||
};
|
||||
};
|
||||
|
||||
public KeyguardSimPinView(Context context) {
|
||||
this(context, null);
|
||||
@ -53,7 +68,22 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
|
||||
public void resetState() {
|
||||
super.resetState();
|
||||
mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
|
||||
if (DEBUG) Log.v(TAG, "Resetting state");
|
||||
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
|
||||
mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
|
||||
if (mSubId != SubscriptionManager.INVALID_SUB_ID) {
|
||||
int count = TelephonyManager.getDefault().getSimCount();
|
||||
Resources rez = getResources();
|
||||
final String msg;
|
||||
if (count < 2) {
|
||||
msg = rez.getString(R.string.kg_sim_pin_instructions);
|
||||
} else {
|
||||
SubscriptionInfo info = monitor.getSubscriptionInfoForSubId(mSubId);
|
||||
CharSequence displayName = info != null ? info.getDisplayName() : ""; // don't crash
|
||||
msg = rez.getString(R.string.kg_sim_pin_instructions_multi, displayName);
|
||||
}
|
||||
mSecurityMessageDisplay.setMessage(msg, true);
|
||||
}
|
||||
}
|
||||
|
||||
private String getPinPasswordErrorMessage(int attemptsRemaining) {
|
||||
@ -94,6 +124,18 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showUsabilityHint() {
|
||||
}
|
||||
@ -113,9 +155,11 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
*/
|
||||
private abstract class CheckSimPin extends Thread {
|
||||
private final String mPin;
|
||||
private int mSubId;
|
||||
|
||||
protected CheckSimPin(String pin) {
|
||||
protected CheckSimPin(String pin, int subId) {
|
||||
mPin = pin;
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
abstract void onSimCheckResponse(final int result, final int attemptsRemaining);
|
||||
@ -123,10 +167,14 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Log.v(TAG, "call supplyPinReportResult()");
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")");
|
||||
}
|
||||
final int[] result = ITelephony.Stub.asInterface(ServiceManager
|
||||
.checkService("phone")).supplyPinReportResult(mPin);
|
||||
Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]);
|
||||
.checkService("phone")).supplyPinReportResultForSubscriber(mSubId, mPin);
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]);
|
||||
}
|
||||
post(new Runnable() {
|
||||
public void run() {
|
||||
onSimCheckResponse(result[0], result[1]);
|
||||
@ -187,15 +235,17 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
getSimUnlockProgressDialog().show();
|
||||
|
||||
if (mCheckSimPinThread == null) {
|
||||
mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText()) {
|
||||
mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText(), mSubId) {
|
||||
void onSimCheckResponse(final int result, final int attemptsRemaining) {
|
||||
post(new Runnable() {
|
||||
public void run() {
|
||||
if (mSimUnlockProgressDialog != null) {
|
||||
mSimUnlockProgressDialog.hide();
|
||||
}
|
||||
resetPasswordText(true /* animate */);
|
||||
if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
|
||||
KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
|
||||
KeyguardUpdateMonitor.getInstance(getContext())
|
||||
.reportSimUnlocked(mSubId);
|
||||
mCallback.dismiss(true);
|
||||
} else {
|
||||
if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
|
||||
@ -216,7 +266,6 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
|
||||
+ " CheckSimPin.onSimCheckResponse: " + result
|
||||
+ " attemptsRemaining=" + attemptsRemaining);
|
||||
resetPasswordText(true /* animate */);
|
||||
}
|
||||
mCallback.userActivity();
|
||||
mCheckSimPinThread = null;
|
||||
|
@ -17,18 +17,24 @@
|
||||
package com.android.keyguard;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.internal.telephony.ITelephony;
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
import com.android.internal.telephony.IccCardConstants.State;
|
||||
|
||||
|
||||
/**
|
||||
@ -45,6 +51,23 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
private String mPinText;
|
||||
private StateMachine mStateMachine = new StateMachine();
|
||||
private AlertDialog mRemainingAttemptsDialog;
|
||||
private int mSubId;
|
||||
|
||||
KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onSimStateChanged(int subId, int slotId, State simState) {
|
||||
if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
|
||||
resetState();
|
||||
};
|
||||
};
|
||||
|
||||
public KeyguardSimPukView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public KeyguardSimPukView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
private class StateMachine {
|
||||
final int ENTER_PUK = 0;
|
||||
@ -89,7 +112,21 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
mPinText="";
|
||||
mPukText="";
|
||||
state = ENTER_PUK;
|
||||
mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
|
||||
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
|
||||
mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED);
|
||||
if (mSubId != SubscriptionManager.INVALID_SUB_ID) {
|
||||
int count = TelephonyManager.getDefault().getSimCount();
|
||||
Resources rez = getResources();
|
||||
final String msg;
|
||||
if (count < 2) {
|
||||
msg = rez.getString(R.string.kg_puk_enter_puk_hint);
|
||||
} else {
|
||||
SubscriptionInfo info = monitor.getSubscriptionInfoForSubId(mSubId);
|
||||
CharSequence displayName = info != null ? info.getDisplayName() : "";
|
||||
msg = rez.getString(R.string.kg_puk_enter_puk_hint_multi, displayName);
|
||||
}
|
||||
mSecurityMessageDisplay.setMessage(msg, true);
|
||||
}
|
||||
mPasswordEntry.requestFocus();
|
||||
}
|
||||
}
|
||||
@ -111,14 +148,6 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
return displayMessage;
|
||||
}
|
||||
|
||||
public KeyguardSimPukView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public KeyguardSimPukView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void resetState() {
|
||||
super.resetState();
|
||||
mStateMachine.reset();
|
||||
@ -145,6 +174,18 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showUsabilityHint() {
|
||||
}
|
||||
@ -165,10 +206,12 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
private abstract class CheckSimPuk extends Thread {
|
||||
|
||||
private final String mPin, mPuk;
|
||||
private final int mSubId;
|
||||
|
||||
protected CheckSimPuk(String puk, String pin) {
|
||||
protected CheckSimPuk(String puk, String pin, int subId) {
|
||||
mPuk = puk;
|
||||
mPin = pin;
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
abstract void onSimLockChangedResponse(final int result, final int attemptsRemaining);
|
||||
@ -176,10 +219,12 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Log.v(TAG, "call supplyPukReportResult()");
|
||||
if (DEBUG) Log.v(TAG, "call supplyPukReportResult()");
|
||||
final int[] result = ITelephony.Stub.asInterface(ServiceManager
|
||||
.checkService("phone")).supplyPukReportResult(mPuk, mPin);
|
||||
Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]);
|
||||
.checkService("phone")).supplyPukReportResultForSubscriber(mSubId, mPuk, mPin);
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]);
|
||||
}
|
||||
post(new Runnable() {
|
||||
public void run() {
|
||||
onSimLockChangedResponse(result[0], result[1]);
|
||||
@ -254,15 +299,17 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
getSimUnlockProgressDialog().show();
|
||||
|
||||
if (mCheckSimPukThread == null) {
|
||||
mCheckSimPukThread = new CheckSimPuk(mPukText, mPinText) {
|
||||
mCheckSimPukThread = new CheckSimPuk(mPukText, mPinText, mSubId) {
|
||||
void onSimLockChangedResponse(final int result, final int attemptsRemaining) {
|
||||
post(new Runnable() {
|
||||
public void run() {
|
||||
if (mSimUnlockProgressDialog != null) {
|
||||
mSimUnlockProgressDialog.hide();
|
||||
}
|
||||
resetPasswordText(true /* animate */);
|
||||
if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
|
||||
KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
|
||||
KeyguardUpdateMonitor.getInstance(getContext())
|
||||
.reportSimUnlocked(mSubId);
|
||||
mCallback.dismiss(true);
|
||||
} else {
|
||||
if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
|
||||
|
@ -51,11 +51,17 @@ import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.IccCardConstants.State;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.internal.telephony.TelephonyProperties;
|
||||
|
||||
import android.service.fingerprint.FingerprintManager;
|
||||
import android.service.fingerprint.FingerprintManagerReceiver;
|
||||
import android.service.fingerprint.FingerprintUtils;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionListener;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
@ -64,6 +70,9 @@ import com.google.android.collect.Lists;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Watches for updates that may be interesting to the keyguard, and provides
|
||||
@ -79,7 +88,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
|
||||
private static final String TAG = "KeyguardUpdateMonitor";
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
private static final boolean DEBUG_SIM_STATES = DEBUG || false;
|
||||
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
|
||||
private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
|
||||
private static final int LOW_BATTERY_THRESHOLD = 20;
|
||||
|
||||
@ -113,13 +122,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
private static final int MSG_FINGERPRINT_PROCESSED = 323;
|
||||
private static final int MSG_FINGERPRINT_ACQUIRED = 324;
|
||||
private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 325;
|
||||
private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 326;
|
||||
|
||||
private static KeyguardUpdateMonitor sInstance;
|
||||
|
||||
private final Context mContext;
|
||||
HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
|
||||
|
||||
// Telephony state
|
||||
private IccCardConstants.State mSimState = IccCardConstants.State.READY;
|
||||
private CharSequence mTelephonyPlmn;
|
||||
private CharSequence mTelephonySpn;
|
||||
private int mRingMode;
|
||||
@ -149,6 +158,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
private boolean mSwitchingUser;
|
||||
|
||||
private boolean mScreenOn;
|
||||
protected List<SubscriptionInfo> mSubscriptionInfo;
|
||||
|
||||
private final Handler mHandler = new Handler() {
|
||||
@Override
|
||||
@ -164,7 +174,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
handleCarrierInfoUpdate();
|
||||
break;
|
||||
case MSG_SIM_STATE_CHANGE:
|
||||
handleSimStateChange((SimArgs) msg.obj);
|
||||
handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
|
||||
break;
|
||||
case MSG_RINGER_MODE_CHANGED:
|
||||
handleRingerModeChange(msg.arg1);
|
||||
@ -220,10 +230,20 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
case MSG_FACE_UNLOCK_STATE_CHANGED:
|
||||
handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
|
||||
break;
|
||||
case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
|
||||
handleSimSubscriptionInfoChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
|
||||
@Override
|
||||
public void onSubscriptionInfoChanged() {
|
||||
mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
|
||||
}
|
||||
};
|
||||
|
||||
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
|
||||
private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
|
||||
private SparseBooleanArray mUserFingerprintRecognized = new SparseBooleanArray();
|
||||
@ -244,6 +264,40 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleSimSubscriptionInfoChanged() {
|
||||
if (DEBUG_SIM_STATES) {
|
||||
Log.v(TAG, "onSubscriptionInfoChanged()");
|
||||
for (SubscriptionInfo subInfo : SubscriptionManager.getActiveSubscriptionInfoList()) {
|
||||
Log.v(TAG, "SubInfo:" + subInfo);
|
||||
}
|
||||
}
|
||||
List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
|
||||
|
||||
// Hack level over 9000: Because the subscription id is not yet valid when we see the
|
||||
// first update in handleSimStateChange, we need to force refresh all all SIM states
|
||||
// so the subscription id for them is consistent.
|
||||
for (int i = 0; i < subscriptionInfos.size(); i++) {
|
||||
SubscriptionInfo info = subscriptionInfos.get(i);
|
||||
refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
|
||||
}
|
||||
for (int i = 0; i < subscriptionInfos.size(); i++) {
|
||||
SimData data = mSimDatas.get(mSubscriptionInfo.get(i).getSubscriptionId());
|
||||
for (int j = 0; j < mCallbacks.size(); j++) {
|
||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
|
||||
if (cb != null) {
|
||||
cb.onSimStateChanged(data.subId, data.slotId, data.simState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
|
||||
if (mSubscriptionInfo == null || forceReload) {
|
||||
mSubscriptionInfo = SubscriptionManager.getActiveSubscriptionInfoList();
|
||||
}
|
||||
return mSubscriptionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrustManagedChanged(boolean managed, int userId) {
|
||||
mUserTrustIsManaged.put(userId, managed);
|
||||
@ -382,12 +436,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
|
||||
mHandler.sendMessage(msg);
|
||||
} else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
|
||||
SimData args = SimData.fromIntent(intent);
|
||||
if (DEBUG_SIM_STATES) {
|
||||
Log.v(TAG, "action " + action + " state" +
|
||||
intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
|
||||
Log.v(TAG, "action " + action
|
||||
+ " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
|
||||
+ " slotId: " + args.slotId + " subid: " + args.subId);
|
||||
}
|
||||
mHandler.sendMessage(mHandler.obtainMessage(
|
||||
MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
|
||||
mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
|
||||
.sendToTarget();
|
||||
} else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
|
||||
intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
|
||||
@ -449,19 +505,26 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
* we need a single object to pass to the handler. This class helps decode
|
||||
* the intent and provide a {@link SimCard.State} result.
|
||||
*/
|
||||
private static class SimArgs {
|
||||
public final IccCardConstants.State simState;
|
||||
private static class SimData {
|
||||
public State simState;
|
||||
public int slotId;
|
||||
public int subId;
|
||||
|
||||
SimArgs(IccCardConstants.State state) {
|
||||
SimData(State state, int slot, int id) {
|
||||
simState = state;
|
||||
slotId = slot;
|
||||
subId = id;
|
||||
}
|
||||
|
||||
static SimArgs fromIntent(Intent intent) {
|
||||
IccCardConstants.State state;
|
||||
static SimData fromIntent(Intent intent) {
|
||||
State state;
|
||||
if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
|
||||
throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
|
||||
}
|
||||
String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
|
||||
int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
|
||||
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
|
||||
SubscriptionManager.INVALID_SUB_ID);
|
||||
if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
|
||||
final String absentReason = intent
|
||||
.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
|
||||
@ -494,11 +557,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
} else {
|
||||
state = IccCardConstants.State.UNKNOWN;
|
||||
}
|
||||
return new SimArgs(state);
|
||||
return new SimData(state, slotId, subId);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return simState.toString();
|
||||
return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -605,7 +668,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
}
|
||||
|
||||
// Take a guess at initial SIM state, battery status and PLMN until we get an update
|
||||
mSimState = IccCardConstants.State.NOT_READY;
|
||||
mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
|
||||
mTelephonyPlmn = getDefaultPlmn();
|
||||
|
||||
@ -636,6 +698,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
|
||||
null, null);
|
||||
|
||||
SubscriptionManager.register(mContext, mSubscriptionListener,
|
||||
SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
|
||||
try {
|
||||
ActivityManagerNative.getDefault().registerUserSwitchObserver(
|
||||
new IUserSwitchObserver.Stub() {
|
||||
@ -881,20 +945,35 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
/**
|
||||
* Handle {@link #MSG_SIM_STATE_CHANGE}
|
||||
*/
|
||||
private void handleSimStateChange(SimArgs simArgs) {
|
||||
final IccCardConstants.State state = simArgs.simState;
|
||||
private void handleSimStateChange(int subId, int slotId, State state) {
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
|
||||
+ "state resolved to " + state.toString());
|
||||
if (DEBUG_SIM_STATES) {
|
||||
Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
|
||||
+ slotId + ", state=" + state +")");
|
||||
}
|
||||
|
||||
if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
|
||||
mSimState = state;
|
||||
if (subId == SubscriptionManager.INVALID_SUB_ID) {
|
||||
Log.w(TAG, "invalid subId in handleSimStateChange()");
|
||||
return;
|
||||
}
|
||||
|
||||
SimData data = mSimDatas.get(subId);
|
||||
final boolean changed;
|
||||
if (data == null) {
|
||||
data = new SimData(state, slotId, subId);
|
||||
mSimDatas.put(subId, data);
|
||||
changed = true; // no data yet; force update
|
||||
} else {
|
||||
changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
|
||||
data.simState = state;
|
||||
data.subId = subId;
|
||||
data.slotId = slotId;
|
||||
}
|
||||
if (changed && state != State.UNKNOWN) {
|
||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||
if (cb != null) {
|
||||
cb.onSimStateChanged(state);
|
||||
cb.onSimStateChanged(subId, slotId, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1070,7 +1149,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
callback.onPhoneStateChanged(mPhoneState);
|
||||
callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
|
||||
callback.onClockVisibilityChanged();
|
||||
callback.onSimStateChanged(mSimState);
|
||||
for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
|
||||
final SimData state = data.getValue();
|
||||
callback.onSimStateChanged(state.subId, state.slotId, state.simState);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendKeyguardVisibilityChanged(boolean showing) {
|
||||
@ -1095,10 +1177,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
|
||||
}
|
||||
|
||||
public IccCardConstants.State getSimState() {
|
||||
return mSimState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
|
||||
* have the information earlier than waiting for the intent
|
||||
@ -1107,8 +1185,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
* NOTE: Because handleSimStateChange() invokes callbacks immediately without going
|
||||
* through mHandler, this *must* be called from the UI thread.
|
||||
*/
|
||||
public void reportSimUnlocked() {
|
||||
handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
|
||||
public void reportSimUnlocked(int subId) {
|
||||
if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
|
||||
int slotId = SubscriptionManager.getSlotId(subId);
|
||||
handleSimStateChange(subId, slotId, State.READY);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1184,18 +1264,44 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
mAlternateUnlockEnabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isSimLocked() {
|
||||
return isSimLocked(mSimState);
|
||||
}
|
||||
|
||||
public static boolean isSimLocked(IccCardConstants.State state) {
|
||||
return state == IccCardConstants.State.PIN_REQUIRED
|
||||
|| state == IccCardConstants.State.PUK_REQUIRED
|
||||
|| state == IccCardConstants.State.PERM_DISABLED;
|
||||
public boolean isSimPinVoiceSecure() {
|
||||
// TODO: only count SIMs that handle voice
|
||||
return isSimPinSecure();
|
||||
}
|
||||
|
||||
public boolean isSimPinSecure() {
|
||||
return isSimPinSecure(mSimState);
|
||||
// True if any SIM is pin secure
|
||||
for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
|
||||
if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private State getSimState(int subId) {
|
||||
if (mSimDatas.containsKey(subId)) {
|
||||
return mSimDatas.get(subId).simState;
|
||||
} else {
|
||||
return State.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshSimState(int subId, int slotId) {
|
||||
|
||||
// This is awful. It exists because there are two APIs for getting the SIM status
|
||||
// that don't return the complete set of values and have different types. In Keyguard we
|
||||
// need IccCardConstants, but TelephonyManager would only give us
|
||||
// TelephonyManager.SIM_STATE*, so we retrieve it manually.
|
||||
final int phoneId = SubscriptionManager.getPhoneId(subId);
|
||||
final String stateString = TelephonyManager.getTelephonyProperty(phoneId,
|
||||
TelephonyProperties.PROPERTY_SIM_STATE, "");
|
||||
State state;
|
||||
try {
|
||||
state = State.valueOf(stateString);
|
||||
} catch(IllegalArgumentException ex) {
|
||||
Log.w(TAG, "Unknown sim state: " + stateString);
|
||||
state = State.UNKNOWN;
|
||||
}
|
||||
mSimDatas.put(subId, new SimData(state, slotId, subId));
|
||||
}
|
||||
|
||||
public static boolean isSimPinSecure(IccCardConstants.State state) {
|
||||
@ -1228,4 +1334,34 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
public boolean isScreenOn() {
|
||||
return mScreenOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
|
||||
* @param state
|
||||
* @return subid or {@link SubscriptionManager#INVALID_SUB_ID} if none found
|
||||
*/
|
||||
public int getNextSubIdForState(State state) {
|
||||
List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
|
||||
int resultId = SubscriptionManager.INVALID_SUB_ID;
|
||||
int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
final SubscriptionInfo info = list.get(i);
|
||||
final int id = info.getSubscriptionId();
|
||||
int slotId = SubscriptionManager.getSlotId(id);
|
||||
if (state == getSimState(id) && bestSlotId > slotId ) {
|
||||
resultId = id;
|
||||
bestSlotId = slotId;
|
||||
}
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
|
||||
List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
SubscriptionInfo info = list.get(i);
|
||||
if (subId == info.getSubscriptionId()) return info;
|
||||
}
|
||||
return null; // not found
|
||||
}
|
||||
}
|
||||
|
@ -121,9 +121,10 @@ public class KeyguardUpdateMonitorCallback {
|
||||
|
||||
/**
|
||||
* Called when the SIM state changes.
|
||||
* @param slotId
|
||||
* @param simState
|
||||
*/
|
||||
public void onSimStateChanged(IccCardConstants.State simState) { }
|
||||
public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) { }
|
||||
|
||||
/**
|
||||
* Called when a user is removed.
|
||||
|
@ -43,6 +43,7 @@ import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
@ -57,6 +58,7 @@ import com.android.internal.policy.IKeyguardExitCallback;
|
||||
import com.android.internal.policy.IKeyguardShowCallback;
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardConstants;
|
||||
import com.android.keyguard.KeyguardDisplayManager;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
@ -116,7 +118,8 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
|
||||
private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;
|
||||
|
||||
final static boolean DEBUG = false;
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
|
||||
private final static boolean DBG_WAKE = false;
|
||||
|
||||
private final static String TAG = "KeyguardViewMediator";
|
||||
@ -360,8 +363,12 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSimStateChanged(IccCardConstants.State simState) {
|
||||
if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState);
|
||||
public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) {
|
||||
|
||||
if (DEBUG_SIM_STATES) {
|
||||
Log.d(TAG, "onSimStateChanged(subId=" + subId + ", slotId=" + slotId
|
||||
+ ",state=" + simState + ")");
|
||||
}
|
||||
|
||||
switch (simState) {
|
||||
case NOT_READY:
|
||||
@ -371,7 +378,7 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
synchronized (this) {
|
||||
if (shouldWaitForProvisioning()) {
|
||||
if (!isShowing()) {
|
||||
if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
|
||||
if (DEBUG_SIM_STATES) Log.d(TAG, "ICC_ABSENT isn't showing,"
|
||||
+ " we need to show the keyguard since the "
|
||||
+ "device isn't provisioned yet.");
|
||||
doKeyguardLocked(null);
|
||||
@ -385,7 +392,8 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
case PUK_REQUIRED:
|
||||
synchronized (this) {
|
||||
if (!isShowing()) {
|
||||
if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
|
||||
if (DEBUG_SIM_STATES) Log.d(TAG,
|
||||
"INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
|
||||
+ "showing; need to show keyguard so user can enter sim pin");
|
||||
doKeyguardLocked(null);
|
||||
} else {
|
||||
@ -396,11 +404,11 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
case PERM_DISABLED:
|
||||
synchronized (this) {
|
||||
if (!isShowing()) {
|
||||
if (DEBUG) Log.d(TAG, "PERM_DISABLED and "
|
||||
if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED and "
|
||||
+ "keygaurd isn't showing.");
|
||||
doKeyguardLocked(null);
|
||||
} else {
|
||||
if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
|
||||
if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
|
||||
+ "show permanently disabled message in lockscreen.");
|
||||
resetStateLocked();
|
||||
}
|
||||
@ -413,6 +421,9 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (DEBUG_SIM_STATES) Log.v(TAG, "Ignoring state: " + simState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -913,13 +924,13 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
}
|
||||
|
||||
// if the setup wizard hasn't run yet, don't show
|
||||
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
|
||||
false);
|
||||
final IccCardConstants.State state = mUpdateMonitor.getSimState();
|
||||
final boolean lockedOrMissing = state.isPinLocked()
|
||||
|| ((state == IccCardConstants.State.ABSENT
|
||||
|| state == IccCardConstants.State.PERM_DISABLED)
|
||||
&& requireSim);
|
||||
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
|
||||
final boolean absent = mUpdateMonitor.getNextSubIdForState(
|
||||
IccCardConstants.State.ABSENT) != SubscriptionManager.INVALID_SUB_ID;
|
||||
final boolean disabled = mUpdateMonitor.getNextSubIdForState(
|
||||
IccCardConstants.State.PERM_DISABLED) != SubscriptionManager.INVALID_SUB_ID;
|
||||
final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
|
||||
|| ((absent || disabled) && requireSim);
|
||||
|
||||
if (!lockedOrMissing && shouldWaitForProvisioning()) {
|
||||
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
|
||||
|
Reference in New Issue
Block a user