1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16.  
  17. package com.android.keyguard;
  18.  
  19. import com.android.internal.telephony.ITelephony;
  20. import com.android.internal.telephony.IccCardConstants;
  21. import com.android.internal.telephony.IccCardConstants.State;
  22. import com.android.internal.telephony.PhoneConstants;
  23.  
  24. import android.content.Context;
  25. import android.content.res.ColorStateList;
  26. import android.content.res.Configuration;
  27. import android.content.res.Resources;
  28. import android.app.AlertDialog;
  29. import android.app.AlertDialog.Builder;
  30. import android.app.Dialog;
  31. import android.app.ProgressDialog;
  32. import android.graphics.Color;
  33. import android.os.RemoteException;
  34. import android.os.ServiceManager;
  35. import android.telephony.SubscriptionInfo;
  36. import android.telephony.SubscriptionManager;
  37. import android.telephony.TelephonyManager;
  38. import android.telephony.euicc.EuiccManager;
  39. import android.util.AttributeSet;
  40. import android.util.Log;
  41. import android.view.View;
  42. import android.view.WindowManager;
  43. import android.widget.ImageView;
  44.  
  45. /**
  46. * Displays a PIN pad for unlocking.
  47. */
  48. public class KeyguardSimPinView extends KeyguardPinBasedInputView {
  49. private static final String LOG_TAG = "KeyguardSimPinView";
  50. private static final boolean DEBUG = KeyguardConstants.DEBUG_SIM_STATES;
  51. public static final String TAG = "KeyguardSimPinView";
  52.  
  53. private ProgressDialog mSimUnlockProgressDialog = null;
  54. private CheckSimPin mCheckSimPinThread;
  55.  
  56. // Below flag is set to true during power-up or when a new SIM card inserted on device.
  57. // When this is true and when SIM card is PIN locked state, on PIN lock screen, message would
  58. // be displayed to inform user about the number of remaining PIN attempts left.
  59. private boolean mShowDefaultMessage = true;
  60. private int mRemainingAttempts = -1;
  61. private AlertDialog mRemainingAttemptsDialog;
  62. private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
  63. private ImageView mSimImageView;
  64.  
  65. KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
  66. @Override
  67. public void onSimStateChanged(int subId, int slotId, State simState) {
  68. if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
  69. switch(simState) {
  70. // If the SIM is removed, then we must remove the keyguard. It will be put up
  71. // again when the PUK locked SIM is re-entered.
  72. case ABSENT: {
  73. KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId);
  74. // onSimStateChanged callback can fire when the SIM PIN lock is not currently
  75. // active and mCallback is null.
  76. if (mCallback != null) {
  77. mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
  78. }
  79. break;
  80. }
  81. case READY: {
  82. mRemainingAttempts = -1;
  83. resetState();
  84. break;
  85. }
  86. default:
  87. resetState();
  88. }
  89. }
  90. };
  91.  
  92. public KeyguardSimPinView(Context context) {
  93. this(context, null);
  94. }
  95.  
  96. public KeyguardSimPinView(Context context, AttributeSet attrs) {
  97. super(context, attrs);
  98. }
  99.  
  100. @Override
  101. public void resetState() {
  102. super.resetState();
  103. if (DEBUG) Log.v(TAG, "Resetting state");
  104. handleSubInfoChangeIfNeeded();
  105. if (mShowDefaultMessage) {
  106. showDefaultMessage();
  107. }
  108. boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
  109.  
  110. KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
  111. esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
  112. }
  113.  
  114. private void showDefaultMessage() {
  115. if (mRemainingAttempts >= 0) {
  116. mSecurityMessageDisplay.setMessage(getPinPasswordErrorMessage(
  117. mRemainingAttempts, true));
  118. return;
  119. }
  120.  
  121. boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
  122. int count = TelephonyManager.getDefault().getSimCount();
  123. Resources rez = getResources();
  124. String msg;
  125. int color = Color.WHITE;
  126. if (count < 2) {
  127. msg = rez.getString(R.string.kg_sim_pin_instructions);
  128. } else {
  129. SubscriptionInfo info = KeyguardUpdateMonitor.getInstance(mContext).
  130. getSubscriptionInfoForSubId(mSubId);
  131. CharSequence displayName = info != null ? info.getDisplayName() : ""; // don't crash
  132. msg = rez.getString(R.string.kg_sim_pin_instructions_multi, displayName);
  133. if (info != null) {
  134. color = info.getIconTint();
  135. }
  136. }
  137.  
  138. if (isEsimLocked) {
  139. msg = rez.getString(R.string.kg_sim_lock_esim_instructions, msg);
  140. }
  141.  
  142. mSecurityMessageDisplay.setMessage(msg);
  143. mSimImageView.setImageTintList(ColorStateList.valueOf(color));
  144.  
  145. // Sending empty PIN here to query the number of remaining PIN attempts
  146. new CheckSimPin("", mSubId) {
  147. void onSimCheckResponse(final int result, final int attemptsRemaining) {
  148. Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result" + result +
  149. " attemptsRemaining=" + attemptsRemaining);
  150. if (attemptsRemaining >= 0) {
  151. mRemainingAttempts = attemptsRemaining;
  152. mSecurityMessageDisplay.setMessage(
  153. getPinPasswordErrorMessage(attemptsRemaining, true));
  154. }
  155. }
  156. }.start();
  157. }
  158.  
  159. private void handleSubInfoChangeIfNeeded() {
  160. KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
  161. int subId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
  162. if (subId != mSubId && SubscriptionManager.isValidSubscriptionId(subId)) {
  163. mSubId = subId;
  164. mShowDefaultMessage = true;
  165. mRemainingAttempts = -1;
  166. }
  167. }
  168.  
  169. @Override
  170. protected void onConfigurationChanged(Configuration newConfig) {
  171. super.onConfigurationChanged(newConfig);
  172. resetState();
  173. }
  174.  
  175. @Override
  176. protected int getPromptReasonStringRes(int reason) {
  177. // No message on SIM Pin
  178. return 0;
  179. }
  180.  
  181. private String getPinPasswordErrorMessage(int attemptsRemaining, boolean isDefault) {
  182. String displayMessage;
  183. int msgId;
  184. if (attemptsRemaining == 0) {
  185. displayMessage = getContext().getString(R.string.kg_password_wrong_pin_code_pukked);
  186. } else if (attemptsRemaining > 0) {
  187. msgId = isDefault ? R.plurals.kg_password_default_pin_message :
  188. R.plurals.kg_password_wrong_pin_code;
  189. displayMessage = getContext().getResources()
  190. .getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
  191. } else {
  192. msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed;
  193. displayMessage = getContext().getString(msgId);
  194. }
  195. if (KeyguardEsimArea.isEsimLocked(mContext, mSubId)) {
  196. displayMessage = getResources()
  197. .getString(R.string.kg_sim_lock_esim_instructions, displayMessage);
  198. }
  199. if (DEBUG) Log.d(LOG_TAG, "getPinPasswordErrorMessage:"
  200. + " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage);
  201. return displayMessage;
  202. }
  203.  
  204. @Override
  205. protected boolean shouldLockout(long deadline) {
  206. // SIM PIN doesn't have a timed lockout
  207. return false;
  208. }
  209.  
  210. @Override
  211. protected int getPasswordTextViewId() {
  212. return R.id.simPinEntry;
  213. }
  214.  
  215. @Override
  216. protected void onFinishInflate() {
  217. super.onFinishInflate();
  218.  
  219. if (mEcaView instanceof EmergencyCarrierArea) {
  220. ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
  221. }
  222. mSimImageView = findViewById(R.id.keyguard_sim);
  223. }
  224.  
  225. @Override
  226. protected void onAttachedToWindow() {
  227. super.onAttachedToWindow();
  228. KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
  229. }
  230.  
  231. @Override
  232. protected void onDetachedFromWindow() {
  233. super.onDetachedFromWindow();
  234. KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
  235. }
  236.  
  237. @Override
  238. public void showUsabilityHint() {
  239. }
  240.  
  241. @Override
  242. public void onPause() {
  243. // dismiss the dialog.
  244. if (mSimUnlockProgressDialog != null) {
  245. mSimUnlockProgressDialog.dismiss();
  246. mSimUnlockProgressDialog = null;
  247. }
  248. }
  249.  
  250. /**
  251. * Since the IPC can block, we want to run the request in a separate thread
  252. * with a callback.
  253. */
  254. private abstract class CheckSimPin extends Thread {
  255. private final String mPin;
  256. private int mSubId;
  257.  
  258. protected CheckSimPin(String pin, int subId) {
  259. mPin = pin;
  260. mSubId = subId;
  261. }
  262.  
  263. abstract void onSimCheckResponse(final int result, final int attemptsRemaining);
  264.  
  265. @Override
  266. public void run() {
  267. try {
  268. if (DEBUG) {
  269. Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")");
  270. }
  271. final int[] result = ITelephony.Stub.asInterface(ServiceManager
  272. .checkService("phone")).supplyPinReportResultForSubscriber(mSubId, mPin);
  273. if (DEBUG) {
  274. Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]);
  275. }
  276. post(new Runnable() {
  277. @Override
  278. public void run() {
  279. onSimCheckResponse(result[0], result[1]);
  280. }
  281. });
  282. } catch (RemoteException e) {
  283. Log.e(TAG, "RemoteException for supplyPinReportResult:", e);
  284. post(new Runnable() {
  285. @Override
  286. public void run() {
  287. onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1);
  288. }
  289. });
  290. }
  291. }
  292. }
  293.  
  294. private Dialog getSimUnlockProgressDialog() {
  295. if (mSimUnlockProgressDialog == null) {
  296. mSimUnlockProgressDialog = new ProgressDialog(mContext);
  297. mSimUnlockProgressDialog.setMessage(
  298. mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
  299. mSimUnlockProgressDialog.setIndeterminate(true);
  300. mSimUnlockProgressDialog.setCancelable(false);
  301. mSimUnlockProgressDialog.getWindow().setType(
  302. WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
  303. }
  304. return mSimUnlockProgressDialog;
  305. }
  306.  
  307. private Dialog getSimRemainingAttemptsDialog(int remaining) {
  308. String msg = getPinPasswordErrorMessage(remaining, false);
  309. if (mRemainingAttemptsDialog == null) {
  310. Builder builder = new AlertDialog.Builder(mContext);
  311. builder.setMessage(msg);
  312. builder.setCancelable(false);
  313. builder.setNeutralButton(R.string.ok, null);
  314. mRemainingAttemptsDialog = builder.create();
  315. mRemainingAttemptsDialog.getWindow().setType(
  316. WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
  317. } else {
  318. mRemainingAttemptsDialog.setMessage(msg);
  319. }
  320. return mRemainingAttemptsDialog;
  321. }
  322.  
  323. @Override
  324. protected void verifyPasswordAndUnlock() {
  325. String entry = mPasswordEntry.getText();
  326.  
  327. if (entry.length() < 4) {
  328. // otherwise, display a message to the user, and don't submit.
  329. mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint);
  330. resetPasswordText(true /* animate */, true /* announce */);
  331. mCallback.userActivity();
  332. return;
  333. }
  334.  
  335. getSimUnlockProgressDialog().show();
  336.  
  337. if (mCheckSimPinThread == null) {
  338. mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText(), mSubId) {
  339. @Override
  340. void onSimCheckResponse(final int result, final int attemptsRemaining) {
  341. post(new Runnable() {
  342. @Override
  343. public void run() {
  344. mRemainingAttempts = attemptsRemaining;
  345. if (mSimUnlockProgressDialog != null) {
  346. mSimUnlockProgressDialog.hide();
  347. }
  348. resetPasswordText(true /* animate */,
  349. result != PhoneConstants.PIN_RESULT_SUCCESS /* announce */);
  350. if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
  351. KeyguardUpdateMonitor.getInstance(getContext())
  352. .reportSimUnlocked(mSubId);
  353. mRemainingAttempts = -1;
  354. mShowDefaultMessage = true;
  355. if (mCallback != null) {
  356. mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
  357. }
  358. } else {
  359. mShowDefaultMessage = false;
  360. if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
  361. if (attemptsRemaining <= 2) {
  362. // this is getting critical - show dialog
  363. getSimRemainingAttemptsDialog(attemptsRemaining).show();
  364. } else {
  365. // show message
  366. mSecurityMessageDisplay.setMessage(
  367. getPinPasswordErrorMessage(attemptsRemaining, false));
  368. }
  369. } else {
  370. // "PIN operation failed!" - no idea what this was and no way to
  371. // find out. :/
  372. mSecurityMessageDisplay.setMessage(getContext().getString(
  373. R.string.kg_password_pin_failed));
  374. }
  375. if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
  376. + " CheckSimPin.onSimCheckResponse: " + result
  377. + " attemptsRemaining=" + attemptsRemaining);
  378. }
  379. mCallback.userActivity();
  380. mCheckSimPinThread = null;
  381. }
  382. });
  383. }
  384. };
  385. mCheckSimPinThread.start();
  386. }
  387. }
  388.  
  389. @Override
  390. public void startAppearAnimation() {
  391. // noop.
  392. }
  393.  
  394. @Override
  395. public boolean startDisappearAnimation(Runnable finishRunnable) {
  396. return false;
  397. }
  398.  
  399. @Override
  400. public CharSequence getTitle() {
  401. return getContext().getString(
  402. com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
  403. }
  404. }
  1. /*
    * 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.
    */
  2.  
  3. package com.android.keyguard;
  4.  
  5. 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;
  6.  
  7. 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;
  8.  
  9. /**
    * 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";
  10.  
  11. private ProgressDialog mSimUnlockProgressDialog = null;
    private CheckSimPin mCheckSimPinThread;
  12.  
  13. // 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;
  14.  
  15. 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();
    }
    }
    };
  16.  
  17. public KeyguardSimPinView(Context context) {
    this(context, null);
    }
  18.  
  19. public KeyguardSimPinView(Context context, AttributeSet attrs) {
    super(context, attrs);
    }
  20.  
  21. @Override
    public void resetState() {
    super.resetState();
    if (DEBUG) Log.v(TAG, "Resetting state");
    handleSubInfoChangeIfNeeded();
    if (mShowDefaultMessage) {
    showDefaultMessage();
    }
    boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
  22.  
  23. KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
    esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
    }
  24.  
  25. private void showDefaultMessage() {
    if (mRemainingAttempts >= ) {
    mSecurityMessageDisplay.setMessage(getPinPasswordErrorMessage(
    mRemainingAttempts, true));
    return;
    }
  26.  
  27. 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();
    }
    }
  28.  
  29. if (isEsimLocked) {
    msg = rez.getString(R.string.kg_sim_lock_esim_instructions, msg);
    }
  30.  
  31. mSecurityMessageDisplay.setMessage(msg);
    mSimImageView.setImageTintList(ColorStateList.valueOf(color));
  32.  
  33. // 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();
    }
  34.  
  35. 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 = -;
    }
    }
  36.  
  37. @Override
    protected void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    resetState();
    }
  38.  
  39. @Override
    protected int getPromptReasonStringRes(int reason) {
    // No message on SIM Pin
    return ;
    }
  40.  
  41. 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;
    }
  42.  
  43. @Override
    protected boolean shouldLockout(long deadline) {
    // SIM PIN doesn't have a timed lockout
    return false;
    }
  44.  
  45. @Override
    protected int getPasswordTextViewId() {
    return R.id.simPinEntry;
    }
  46.  
  47. @Override
    protected void onFinishInflate() {
    super.onFinishInflate();
  48.  
  49. if (mEcaView instanceof EmergencyCarrierArea) {
    ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
    }
    mSimImageView = findViewById(R.id.keyguard_sim);
    }
  50.  
  51. @Override
    protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
    }
  52.  
  53. @Override
    protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
    }
  54.  
  55. @Override
    public void showUsabilityHint() {
    }
  56.  
  57. @Override
    public void onPause() {
    // dismiss the dialog.
    if (mSimUnlockProgressDialog != null) {
    mSimUnlockProgressDialog.dismiss();
    mSimUnlockProgressDialog = null;
    }
    }
  58.  
  59. /**
    * 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;
  60.  
  61. protected CheckSimPin(String pin, int subId) {
    mPin = pin;
    mSubId = subId;
    }
  62.  
  63. abstract void onSimCheckResponse(final int result, final int attemptsRemaining);
  64.  
  65. @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, -);
    }
    });
    }
    }
    }
  66.  
  67. 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;
    }
  68.  
  69. 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;
    }
  70.  
  71. @Override
    protected void verifyPasswordAndUnlock() {
    String entry = mPasswordEntry.getText();
  72.  
  73. 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;
    }
  74.  
  75. getSimUnlockProgressDialog().show();
  76.  
  77. 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();
    }
    }
  78.  
  79. @Override
    public void startAppearAnimation() {
    // noop.
    }
  80.  
  81. @Override
    public boolean startDisappearAnimation(Runnable finishRunnable) {
    return false;
    }
  82.  
  83. @Override
    public CharSequence getTitle() {
    return getContext().getString(
    com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
    }
    }

KeyguardSimPinView的更多相关文章

  1. Android Framework 其中A记录

    一个简短的引论 以往的研究太偏应用层的功能,实现了,原则上不进入非常理解,现在,研究人员framework该框架层. 创纪录的 1.下载源代码,文件夹例如以下: 2.Android系统的层次例如以下: ...

  2. Android Framework 学习和需要学习的内容

    1. 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework面存一些资料待有空查看. 2.Android系统的层次如下: 3.项目目录简单分析如下: 4.telphony ...

  3. Android Framework 简介

    Android Framework 简介 简介 之前的研究太偏向应用层功能实现了,很多原理不了解没有详记,结果被很多公司技术人员鄙视了,为了减少自己的短板,重新复习了一遍C++.java.Androi ...

  4. Android Framework 记录之一

    简介 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework框架层了. 记录 1.下载源码,目录如下: 2.Android系统的层次如下: 3.项目目录简单分析如下: 4 ...

  5. Android Framework 学习

    1. 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework面存一些资料待有空查看. 2.Android系统的层次如下: 3.项目目录简单分析如下: 4.telphony ...

随机推荐

  1. DHCP协议分析(Wireshark)

    一.说明 一是很多时候IP都是设置成通过dhcp动态获取的,但一直不太清楚dhcp的具体交互过程:二是加上前几天有同事问知不知道DHCP具体交互过程:三是这两天正好在分析协议.所以就顺道来看一下. 如 ...

  2. .net实现网易云音乐下载

    客户端版的网易云音乐下载是需要vip的,网页版的虽然可以通过调试工具找到下载链接,但是用起来不是很方便,通过调试工具观察请求发现请求参数都是加密的,比如搜索歌曲的请求参数: 这个加密的实现肯定是写在j ...

  3. java使用SimpleDateFormat实现字符串和日期的相互转换

    public class TimeTwo { public static void main(String[] args) throws ParseException{ String s = &quo ...

  4. css继承属性

    在css中我们经常会遇到一些子元素继承父元素的情况 , 有时候不清楚有哪些属性会继承, 在开发中会给我们带来一些麻烦 ,稍作整理还是很有必要. 一.有继承性的属性 1.字体系列属性 font:组合字体 ...

  5. selenium自动化实例: 多层框架中关于iframe的定位,以及select下拉框选择

    对于一个自动化的初学者来说会很常见的遇到元素明明存在却始终定位不到, 从而导致脚本报错,当然定位不到元素的原因很多, 其中一种就是多层框架iframe导致的 下方截图示意: 下方为写脚本时候的示例并其 ...

  6. 假如有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小

    假如有Thread1.Thread2.Thread3.Thread4四条线程分别统计C.D.E.F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现? 实现1:用concur ...

  7. 清除冗余的css

    下载旧版的火狐浏览器,如Firefox 48.0.exe, 下载地址:https://ftp.mozilla.org/pub/firefox/releases/48.0/win32/zh-CN 关闭更 ...

  8. ImportError: No module named _tkinter, please install the python-tk package ubuntu运行tkinter错误

    这是由于Python的版本没有包含tkinter的模块,只需要把tk的package安装就可以了. 一般在Linux才出现,windows版本一般已经包含了tkinter模块. apt-get ins ...

  9. js中三种弹出框

    javascript的三种对话框是通过调用window对象的三个方法alert(),confirm()和prompt()来获得,可以利用这些对话框来完成js的输入和输出,实现与用户能进行交互的js代码 ...

  10. nginx配置ssl证书

    一:加装nginx的ssl模块 1.1:切换到源码包 cd /zz/nginx-1.14.2 1.2:查看已安装模块 /usr/local/nginx/sbin/nginx -V [root@game ...