KeyguardSimPinView
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ 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.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView; /**
* Displays a PIN pad for unlocking.
*/
public class KeyguardSimPinView extends KeyguardPinBasedInputView {
private static final String LOG_TAG = "KeyguardSimPinView";
private static final boolean DEBUG = KeyguardConstants.DEBUG_SIM_STATES;
public static final String TAG = "KeyguardSimPinView"; private ProgressDialog mSimUnlockProgressDialog = null;
private CheckSimPin mCheckSimPinThread; // Below flag is set to true during power-up or when a new SIM card inserted on device.
// When this is true and when SIM card is PIN locked state, on PIN lock screen, message would
// be displayed to inform user about the number of remaining PIN attempts left.
private boolean mShowDefaultMessage = true;
private int mRemainingAttempts = -1;
private AlertDialog mRemainingAttemptsDialog;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private ImageView mSimImageView; KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onSimStateChanged(int subId, int slotId, State simState) {
if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
switch(simState) {
// If the SIM is removed, then we must remove the keyguard. It will be put up
// again when the PUK locked SIM is re-entered.
case ABSENT: {
KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId);
// onSimStateChanged callback can fire when the SIM PIN lock is not currently
// active and mCallback is null.
if (mCallback != null) {
mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
}
break;
}
case READY: {
mRemainingAttempts = -1;
resetState();
break;
}
default:
resetState();
}
}
}; public KeyguardSimPinView(Context context) {
this(context, null);
} public KeyguardSimPinView(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
public void resetState() {
super.resetState();
if (DEBUG) Log.v(TAG, "Resetting state");
handleSubInfoChangeIfNeeded();
if (mShowDefaultMessage) {
showDefaultMessage();
}
boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId); KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
} private void showDefaultMessage() {
if (mRemainingAttempts >= 0) {
mSecurityMessageDisplay.setMessage(getPinPasswordErrorMessage(
mRemainingAttempts, true));
return;
} boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
int count = TelephonyManager.getDefault().getSimCount();
Resources rez = getResources();
String msg;
int color = Color.WHITE;
if (count < 2) {
msg = rez.getString(R.string.kg_sim_pin_instructions);
} else {
SubscriptionInfo info = KeyguardUpdateMonitor.getInstance(mContext).
getSubscriptionInfoForSubId(mSubId);
CharSequence displayName = info != null ? info.getDisplayName() : ""; // don't crash
msg = rez.getString(R.string.kg_sim_pin_instructions_multi, displayName);
if (info != null) {
color = info.getIconTint();
}
} if (isEsimLocked) {
msg = rez.getString(R.string.kg_sim_lock_esim_instructions, msg);
} mSecurityMessageDisplay.setMessage(msg);
mSimImageView.setImageTintList(ColorStateList.valueOf(color)); // Sending empty PIN here to query the number of remaining PIN attempts
new CheckSimPin("", mSubId) {
void onSimCheckResponse(final int result, final int attemptsRemaining) {
Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result" + result +
" attemptsRemaining=" + attemptsRemaining);
if (attemptsRemaining >= 0) {
mRemainingAttempts = attemptsRemaining;
mSecurityMessageDisplay.setMessage(
getPinPasswordErrorMessage(attemptsRemaining, true));
}
}
}.start();
} private void handleSubInfoChangeIfNeeded() {
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
int subId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
if (subId != mSubId && SubscriptionManager.isValidSubscriptionId(subId)) {
mSubId = subId;
mShowDefaultMessage = true;
mRemainingAttempts = -1;
}
} @Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
resetState();
} @Override
protected int getPromptReasonStringRes(int reason) {
// No message on SIM Pin
return 0;
} private String getPinPasswordErrorMessage(int attemptsRemaining, boolean isDefault) {
String displayMessage;
int msgId;
if (attemptsRemaining == 0) {
displayMessage = getContext().getString(R.string.kg_password_wrong_pin_code_pukked);
} else if (attemptsRemaining > 0) {
msgId = isDefault ? R.plurals.kg_password_default_pin_message :
R.plurals.kg_password_wrong_pin_code;
displayMessage = getContext().getResources()
.getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
} else {
msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed;
displayMessage = getContext().getString(msgId);
}
if (KeyguardEsimArea.isEsimLocked(mContext, mSubId)) {
displayMessage = getResources()
.getString(R.string.kg_sim_lock_esim_instructions, displayMessage);
}
if (DEBUG) Log.d(LOG_TAG, "getPinPasswordErrorMessage:"
+ " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage);
return displayMessage;
} @Override
protected boolean shouldLockout(long deadline) {
// SIM PIN doesn't have a timed lockout
return false;
} @Override
protected int getPasswordTextViewId() {
return R.id.simPinEntry;
} @Override
protected void onFinishInflate() {
super.onFinishInflate(); if (mEcaView instanceof EmergencyCarrierArea) {
((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
}
mSimImageView = findViewById(R.id.keyguard_sim);
} @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() {
} @Override
public void onPause() {
// dismiss the dialog.
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.dismiss();
mSimUnlockProgressDialog = null;
}
} /**
* Since the IPC can block, we want to run the request in a separate thread
* with a callback.
*/
private abstract class CheckSimPin extends Thread {
private final String mPin;
private int mSubId; protected CheckSimPin(String pin, int subId) {
mPin = pin;
mSubId = subId;
} abstract void onSimCheckResponse(final int result, final int attemptsRemaining); @Override
public void run() {
try {
if (DEBUG) {
Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")");
}
final int[] result = ITelephony.Stub.asInterface(ServiceManager
.checkService("phone")).supplyPinReportResultForSubscriber(mSubId, mPin);
if (DEBUG) {
Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]);
}
post(new Runnable() {
@Override
public void run() {
onSimCheckResponse(result[0], result[1]);
}
});
} catch (RemoteException e) {
Log.e(TAG, "RemoteException for supplyPinReportResult:", e);
post(new Runnable() {
@Override
public void run() {
onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1);
}
});
}
}
} private Dialog getSimUnlockProgressDialog() {
if (mSimUnlockProgressDialog == null) {
mSimUnlockProgressDialog = new ProgressDialog(mContext);
mSimUnlockProgressDialog.setMessage(
mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
mSimUnlockProgressDialog.setIndeterminate(true);
mSimUnlockProgressDialog.setCancelable(false);
mSimUnlockProgressDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
return mSimUnlockProgressDialog;
} private Dialog getSimRemainingAttemptsDialog(int remaining) {
String msg = getPinPasswordErrorMessage(remaining, false);
if (mRemainingAttemptsDialog == null) {
Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(msg);
builder.setCancelable(false);
builder.setNeutralButton(R.string.ok, null);
mRemainingAttemptsDialog = builder.create();
mRemainingAttemptsDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
} else {
mRemainingAttemptsDialog.setMessage(msg);
}
return mRemainingAttemptsDialog;
} @Override
protected void verifyPasswordAndUnlock() {
String entry = mPasswordEntry.getText(); if (entry.length() < 4) {
// otherwise, display a message to the user, and don't submit.
mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint);
resetPasswordText(true /* animate */, true /* announce */);
mCallback.userActivity();
return;
} getSimUnlockProgressDialog().show(); if (mCheckSimPinThread == null) {
mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText(), mSubId) {
@Override
void onSimCheckResponse(final int result, final int attemptsRemaining) {
post(new Runnable() {
@Override
public void run() {
mRemainingAttempts = attemptsRemaining;
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.hide();
}
resetPasswordText(true /* animate */,
result != PhoneConstants.PIN_RESULT_SUCCESS /* announce */);
if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
KeyguardUpdateMonitor.getInstance(getContext())
.reportSimUnlocked(mSubId);
mRemainingAttempts = -1;
mShowDefaultMessage = true;
if (mCallback != null) {
mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
}
} else {
mShowDefaultMessage = false;
if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
if (attemptsRemaining <= 2) {
// this is getting critical - show dialog
getSimRemainingAttemptsDialog(attemptsRemaining).show();
} else {
// show message
mSecurityMessageDisplay.setMessage(
getPinPasswordErrorMessage(attemptsRemaining, false));
}
} else {
// "PIN operation failed!" - no idea what this was and no way to
// find out. :/
mSecurityMessageDisplay.setMessage(getContext().getString(
R.string.kg_password_pin_failed));
}
if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
+ " CheckSimPin.onSimCheckResponse: " + result
+ " attemptsRemaining=" + attemptsRemaining);
}
mCallback.userActivity();
mCheckSimPinThread = null;
}
});
}
};
mCheckSimPinThread.start();
}
} @Override
public void startAppearAnimation() {
// noop.
} @Override
public boolean startDisappearAnimation(Runnable finishRunnable) {
return false;
} @Override
public CharSequence getTitle() {
return getContext().getString(
com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
}
}
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ 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.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView; /**
* Displays a PIN pad for unlocking.
*/
public class KeyguardSimPinView extends KeyguardPinBasedInputView {
private static final String LOG_TAG = "KeyguardSimPinView";
private static final boolean DEBUG = KeyguardConstants.DEBUG_SIM_STATES;
public static final String TAG = "KeyguardSimPinView"; private ProgressDialog mSimUnlockProgressDialog = null;
private CheckSimPin mCheckSimPinThread; // Below flag is set to true during power-up or when a new SIM card inserted on device.
// When this is true and when SIM card is PIN locked state, on PIN lock screen, message would
// be displayed to inform user about the number of remaining PIN attempts left.
private boolean mShowDefaultMessage = true;
private int mRemainingAttempts = -;
private AlertDialog mRemainingAttemptsDialog;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private ImageView mSimImageView; KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onSimStateChanged(int subId, int slotId, State simState) {
if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
switch(simState) {
// If the SIM is removed, then we must remove the keyguard. It will be put up
// again when the PUK locked SIM is re-entered.
case ABSENT: {
KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId);
// onSimStateChanged callback can fire when the SIM PIN lock is not currently
// active and mCallback is null.
if (mCallback != null) {
mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
}
break;
}
case READY: {
mRemainingAttempts = -;
resetState();
break;
}
default:
resetState();
}
}
}; public KeyguardSimPinView(Context context) {
this(context, null);
} public KeyguardSimPinView(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
public void resetState() {
super.resetState();
if (DEBUG) Log.v(TAG, "Resetting state");
handleSubInfoChangeIfNeeded();
if (mShowDefaultMessage) {
showDefaultMessage();
}
boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId); KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
} private void showDefaultMessage() {
if (mRemainingAttempts >= ) {
mSecurityMessageDisplay.setMessage(getPinPasswordErrorMessage(
mRemainingAttempts, true));
return;
} boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
int count = TelephonyManager.getDefault().getSimCount();
Resources rez = getResources();
String msg;
int color = Color.WHITE;
if (count < ) {
msg = rez.getString(R.string.kg_sim_pin_instructions);
} else {
SubscriptionInfo info = KeyguardUpdateMonitor.getInstance(mContext).
getSubscriptionInfoForSubId(mSubId);
CharSequence displayName = info != null ? info.getDisplayName() : ""; // don't crash
msg = rez.getString(R.string.kg_sim_pin_instructions_multi, displayName);
if (info != null) {
color = info.getIconTint();
}
} if (isEsimLocked) {
msg = rez.getString(R.string.kg_sim_lock_esim_instructions, msg);
} mSecurityMessageDisplay.setMessage(msg);
mSimImageView.setImageTintList(ColorStateList.valueOf(color)); // Sending empty PIN here to query the number of remaining PIN attempts
new CheckSimPin("", mSubId) {
void onSimCheckResponse(final int result, final int attemptsRemaining) {
Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result" + result +
" attemptsRemaining=" + attemptsRemaining);
if (attemptsRemaining >= ) {
mRemainingAttempts = attemptsRemaining;
mSecurityMessageDisplay.setMessage(
getPinPasswordErrorMessage(attemptsRemaining, true));
}
}
}.start();
} private void handleSubInfoChangeIfNeeded() {
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
int subId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
if (subId != mSubId && SubscriptionManager.isValidSubscriptionId(subId)) {
mSubId = subId;
mShowDefaultMessage = true;
mRemainingAttempts = -;
}
} @Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
resetState();
} @Override
protected int getPromptReasonStringRes(int reason) {
// No message on SIM Pin
return ;
} private String getPinPasswordErrorMessage(int attemptsRemaining, boolean isDefault) {
String displayMessage;
int msgId;
if (attemptsRemaining == ) {
displayMessage = getContext().getString(R.string.kg_password_wrong_pin_code_pukked);
} else if (attemptsRemaining > ) {
msgId = isDefault ? R.plurals.kg_password_default_pin_message :
R.plurals.kg_password_wrong_pin_code;
displayMessage = getContext().getResources()
.getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
} else {
msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed;
displayMessage = getContext().getString(msgId);
}
if (KeyguardEsimArea.isEsimLocked(mContext, mSubId)) {
displayMessage = getResources()
.getString(R.string.kg_sim_lock_esim_instructions, displayMessage);
}
if (DEBUG) Log.d(LOG_TAG, "getPinPasswordErrorMessage:"
+ " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage);
return displayMessage;
} @Override
protected boolean shouldLockout(long deadline) {
// SIM PIN doesn't have a timed lockout
return false;
} @Override
protected int getPasswordTextViewId() {
return R.id.simPinEntry;
} @Override
protected void onFinishInflate() {
super.onFinishInflate(); if (mEcaView instanceof EmergencyCarrierArea) {
((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
}
mSimImageView = findViewById(R.id.keyguard_sim);
} @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() {
} @Override
public void onPause() {
// dismiss the dialog.
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.dismiss();
mSimUnlockProgressDialog = null;
}
} /**
* Since the IPC can block, we want to run the request in a separate thread
* with a callback.
*/
private abstract class CheckSimPin extends Thread {
private final String mPin;
private int mSubId; protected CheckSimPin(String pin, int subId) {
mPin = pin;
mSubId = subId;
} abstract void onSimCheckResponse(final int result, final int attemptsRemaining); @Override
public void run() {
try {
if (DEBUG) {
Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")");
}
final int[] result = ITelephony.Stub.asInterface(ServiceManager
.checkService("phone")).supplyPinReportResultForSubscriber(mSubId, mPin);
if (DEBUG) {
Log.v(TAG, "supplyPinReportResult returned: " + result[] + " " + result[]);
}
post(new Runnable() {
@Override
public void run() {
onSimCheckResponse(result[], result[]);
}
});
} catch (RemoteException e) {
Log.e(TAG, "RemoteException for supplyPinReportResult:", e);
post(new Runnable() {
@Override
public void run() {
onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -);
}
});
}
}
} private Dialog getSimUnlockProgressDialog() {
if (mSimUnlockProgressDialog == null) {
mSimUnlockProgressDialog = new ProgressDialog(mContext);
mSimUnlockProgressDialog.setMessage(
mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
mSimUnlockProgressDialog.setIndeterminate(true);
mSimUnlockProgressDialog.setCancelable(false);
mSimUnlockProgressDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
return mSimUnlockProgressDialog;
} private Dialog getSimRemainingAttemptsDialog(int remaining) {
String msg = getPinPasswordErrorMessage(remaining, false);
if (mRemainingAttemptsDialog == null) {
Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(msg);
builder.setCancelable(false);
builder.setNeutralButton(R.string.ok, null);
mRemainingAttemptsDialog = builder.create();
mRemainingAttemptsDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
} else {
mRemainingAttemptsDialog.setMessage(msg);
}
return mRemainingAttemptsDialog;
} @Override
protected void verifyPasswordAndUnlock() {
String entry = mPasswordEntry.getText(); if (entry.length() < ) {
// otherwise, display a message to the user, and don't submit.
mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint);
resetPasswordText(true /* animate */, true /* announce */);
mCallback.userActivity();
return;
} getSimUnlockProgressDialog().show(); if (mCheckSimPinThread == null) {
mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText(), mSubId) {
@Override
void onSimCheckResponse(final int result, final int attemptsRemaining) {
post(new Runnable() {
@Override
public void run() {
mRemainingAttempts = attemptsRemaining;
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.hide();
}
resetPasswordText(true /* animate */,
result != PhoneConstants.PIN_RESULT_SUCCESS /* announce */);
if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
KeyguardUpdateMonitor.getInstance(getContext())
.reportSimUnlocked(mSubId);
mRemainingAttempts = -;
mShowDefaultMessage = true;
if (mCallback != null) {
mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
}
} else {
mShowDefaultMessage = false;
if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
if (attemptsRemaining <= ) {
// this is getting critical - show dialog
getSimRemainingAttemptsDialog(attemptsRemaining).show();
} else {
// show message
mSecurityMessageDisplay.setMessage(
getPinPasswordErrorMessage(attemptsRemaining, false));
}
} else {
// "PIN operation failed!" - no idea what this was and no way to
// find out. :/
mSecurityMessageDisplay.setMessage(getContext().getString(
R.string.kg_password_pin_failed));
}
if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
+ " CheckSimPin.onSimCheckResponse: " + result
+ " attemptsRemaining=" + attemptsRemaining);
}
mCallback.userActivity();
mCheckSimPinThread = null;
}
});
}
};
mCheckSimPinThread.start();
}
} @Override
public void startAppearAnimation() {
// noop.
} @Override
public boolean startDisappearAnimation(Runnable finishRunnable) {
return false;
} @Override
public CharSequence getTitle() {
return getContext().getString(
com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
}
}
KeyguardSimPinView的更多相关文章
- Android Framework 其中A记录
一个简短的引论 以往的研究太偏应用层的功能,实现了,原则上不进入非常理解,现在,研究人员framework该框架层. 创纪录的 1.下载源代码,文件夹例如以下: 2.Android系统的层次例如以下: ...
- Android Framework 学习和需要学习的内容
1. 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework面存一些资料待有空查看. 2.Android系统的层次如下: 3.项目目录简单分析如下: 4.telphony ...
- Android Framework 简介
Android Framework 简介 简介 之前的研究太偏向应用层功能实现了,很多原理不了解没有详记,结果被很多公司技术人员鄙视了,为了减少自己的短板,重新复习了一遍C++.java.Androi ...
- Android Framework 记录之一
简介 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework框架层了. 记录 1.下载源码,目录如下: 2.Android系统的层次如下: 3.项目目录简单分析如下: 4 ...
- Android Framework 学习
1. 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework面存一些资料待有空查看. 2.Android系统的层次如下: 3.项目目录简单分析如下: 4.telphony ...
随机推荐
- AES
ES算法之理论与编程结合篇 1 前言 AES是现在使用最多的对称密钥分组密码算法,在逆向的过程中经常碰到,这几天处于离职期,有点时间,于是乎想细细的来研究一下它的原理,也算是离职的一个纪念吧. 网上的 ...
- socket应用(vue、node.js、M站)
socket应用(vue.node.js.M站) 前言:我们在做一些项目的时候需要做到实时变化, 比如我们有时候有需求会要求我们做一个类似于聊天室的页面 比如有些时候我们对某些东西进行点赞和刷票,需要 ...
- Metasploit模块简述
辅助模块.渗透攻击模块.后渗透攻击模块.攻击载荷模块.空指令模块.编码器模块 做了一个思维导图,方便理解. 有需要的就下载吧: 链接:https://share.weiyun.com/5e4XVa1 ...
- css的position
1.标准流2.浮动3.定位块级元素:div.H1-H6.有序及无序列表(ol.ul.li).p内联元素:a.span.img 1. 介绍 1.1 说明 Position 属性:规定元素的定位类型.即元 ...
- JAVA----线程初级
一.认识多任务.多进程.单线程.多线程 要认识多线程就要从操作系统的原理说起. 以前古老的DOS操作系统(V 6.22)是单任务的,还没有线程的概念,系统在每次只能做一件事情.比如你在copy东西 ...
- Python随笔--魔法方法(析构与构造)
#析构方法的调用
- centos7 下zookeeper 部署 单机多实例模式
centos7 下zookeeper 部署 本文参考https://www.linuxidc.com/Linux/2016-09/135052.htm 1.创建/usr/local/zookeeper ...
- uboot使用笔记
一.从最基础的uboot开始 首先是打算直接用程序把已有的镜像烧写进去sd卡里面,但是问题来了,烧写不进去 原因: 可能是windows 7的某些版本和win⑩的系统为了保护磁盘,设定了保护等级,直接 ...
- python logging模块使用流程
#!/usr/local/bin/python # -*- coding:utf-8 -*- import logging logging.debug('debug message') logging ...
- eclipse 中修改项目名称,启动tomct原项目找不到的问题
eclipse 中修改项目名称,启动tomct原项目找不到的问题 1 在开发和练习中,经常会导入其他开源项目,修改项目名称,部署到tomcat 后,然后访问项目会找不到项目,可能是新项目名称和配置文件 ...