blob: 66585c629099b99ffdc4514fd6aa9c110cfc0de5 [file] [log] [blame]
Amith Yamasani655d0e22013-06-12 14:19:10 -07001/*
2 * Copyright (C) 2013 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
17package com.android.internal.app;
18
Amith Yamasani655d0e22013-06-12 14:19:10 -070019import android.content.Context;
Amith Yamasani655d0e22013-06-12 14:19:10 -070020import android.os.Bundle;
21import android.os.UserManager;
22import android.text.Editable;
23import android.text.TextWatcher;
24import android.view.KeyEvent;
25import android.view.LayoutInflater;
26import android.view.View;
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040027import android.view.View.OnClickListener;
28import android.widget.Button;
Amith Yamasani655d0e22013-06-12 14:19:10 -070029import android.widget.EditText;
30import android.widget.TextView;
31import android.widget.TextView.OnEditorActionListener;
32
33import com.android.internal.R;
34
35/**
36 * This activity is launched by Settings and other apps to either create a new PIN or
37 * challenge for an existing PIN. The PIN is maintained by UserManager.
38 */
39public class RestrictionsPinActivity extends AlertActivity
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040040 implements OnClickListener, TextWatcher, OnEditorActionListener {
Amith Yamasani655d0e22013-06-12 14:19:10 -070041
Amith Yamasani1a7472e2013-07-02 11:17:30 -070042 protected UserManager mUserManager;
43 protected boolean mHasRestrictionsPin;
Amith Yamasani655d0e22013-06-12 14:19:10 -070044
Amith Yamasani1a7472e2013-07-02 11:17:30 -070045 protected EditText mPinText;
46 protected TextView mPinErrorMessage;
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040047 private Button mOkButton;
48 private Button mCancelButton;
Amith Yamasani655d0e22013-06-12 14:19:10 -070049
50 @Override
51 public void onCreate(Bundle icicle) {
52 super.onCreate(icicle);
53
Amith Yamasani1a7472e2013-07-02 11:17:30 -070054 mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
Amith Yamasanid304af62013-09-05 09:30:23 -070055 mHasRestrictionsPin = mUserManager.hasRestrictionsChallenge();
Amith Yamasani1a7472e2013-07-02 11:17:30 -070056 initUi();
57 setupAlert();
58 }
59
60 protected void initUi() {
Amith Yamasani655d0e22013-06-12 14:19:10 -070061 AlertController.AlertParams ap = mAlertParams;
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040062 ap.mTitle = getString(R.string.restr_pin_enter_admin_pin);
Amith Yamasani655d0e22013-06-12 14:19:10 -070063 LayoutInflater inflater =
64 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Amith Yamasani1a7472e2013-07-02 11:17:30 -070065 ap.mView = inflater.inflate(R.layout.restrictions_pin_challenge, null);
Amith Yamasani655d0e22013-06-12 14:19:10 -070066
Amith Yamasani655d0e22013-06-12 14:19:10 -070067 mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040068 mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
69 mOkButton = (Button) ap.mView.findViewById(R.id.pin_ok_button);
70 mCancelButton = (Button) ap.mView.findViewById(R.id.pin_cancel_button);
71
Amith Yamasani1a7472e2013-07-02 11:17:30 -070072 mPinText.addTextChangedListener(this);
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040073
74 mOkButton.setOnClickListener(this);
75 mCancelButton.setOnClickListener(this);
Amith Yamasani655d0e22013-06-12 14:19:10 -070076 }
77
78 protected boolean verifyingPin() {
79 return true;
80 }
81
82 public void onResume() {
83 super.onResume();
84
85 setPositiveButtonState(false);
Amith Yamasanid304af62013-09-05 09:30:23 -070086 boolean hasPin = mUserManager.hasRestrictionsChallenge();
Amith Yamasani1a7472e2013-07-02 11:17:30 -070087 if (hasPin) {
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040088 mPinErrorMessage.setVisibility(View.INVISIBLE);
Amith Yamasani1a7472e2013-07-02 11:17:30 -070089 mPinText.setOnEditorActionListener(this);
90 updatePinTimer(-1);
91 } else if (verifyingPin()) {
Amith Yamasani655d0e22013-06-12 14:19:10 -070092 setResult(RESULT_OK);
93 finish();
94 }
95 }
96
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -040097 protected void setPositiveButtonState(boolean enabled) {
98 mOkButton.setEnabled(enabled);
Amith Yamasani655d0e22013-06-12 14:19:10 -070099 }
100
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400101 private boolean updatePinTimer(int pinTimerMs) {
Amith Yamasani655d0e22013-06-12 14:19:10 -0700102 if (pinTimerMs < 0) {
Amith Yamasanid304af62013-09-05 09:30:23 -0700103 pinTimerMs = mUserManager.checkRestrictionsChallenge(null);
Amith Yamasani655d0e22013-06-12 14:19:10 -0700104 }
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400105 boolean enableInput;
Amith Yamasani655d0e22013-06-12 14:19:10 -0700106 if (pinTimerMs >= 200) {
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400107 // Do the count down timer for less than a minute, otherwise just say try again later.
108 if (pinTimerMs <= 60000) {
109 final int seconds = (pinTimerMs + 200) / 1000;
110 final String formatString = getResources().getQuantityString(
111 R.plurals.restr_pin_countdown,
112 seconds);
113 mPinErrorMessage.setText(String.format(formatString, seconds));
114 } else {
115 mPinErrorMessage.setText(R.string.restr_pin_try_later);
116 }
117 enableInput = false;
Amith Yamasani655d0e22013-06-12 14:19:10 -0700118 mPinErrorMessage.setVisibility(View.VISIBLE);
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700119 mPinText.setText("");
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700120 mPinText.postDelayed(mCountdownRunnable, Math.min(1000, pinTimerMs));
Amith Yamasani655d0e22013-06-12 14:19:10 -0700121 } else {
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400122 enableInput = true;
123 mPinErrorMessage.setText(R.string.restr_pin_incorrect);
Amith Yamasani655d0e22013-06-12 14:19:10 -0700124 }
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400125 mPinText.setEnabled(enableInput);
126 setPositiveButtonState(enableInput);
127 return enableInput;
Amith Yamasani655d0e22013-06-12 14:19:10 -0700128 }
129
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700130 protected void performPositiveButtonAction() {
Amith Yamasanid304af62013-09-05 09:30:23 -0700131 int result = mUserManager.checkRestrictionsChallenge(mPinText.getText().toString());
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700132 if (result == UserManager.PIN_VERIFICATION_SUCCESS) {
133 setResult(RESULT_OK);
134 finish();
135 } else if (result >= 0) {
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400136 mPinErrorMessage.setText(R.string.restr_pin_incorrect);
137 mPinErrorMessage.setVisibility(View.VISIBLE);
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700138 updatePinTimer(result);
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400139 mPinText.setText("");
Amith Yamasani655d0e22013-06-12 14:19:10 -0700140 }
141 }
142
143 @Override
144 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
145 }
146
147 @Override
148 public void onTextChanged(CharSequence s, int start, int before, int count) {
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700149 CharSequence pin = mPinText.getText();
150 setPositiveButtonState(pin != null && pin.length() >= 4);
Amith Yamasani655d0e22013-06-12 14:19:10 -0700151 }
152
153 @Override
154 public void afterTextChanged(Editable s) {
155 }
156
157 @Override
158 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
159 performPositiveButtonAction();
160 return true;
161 }
162
163 private Runnable mCountdownRunnable = new Runnable() {
164 public void run() {
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400165 if (updatePinTimer(-1)) {
166 // If we are no longer counting down, clear the message.
167 mPinErrorMessage.setVisibility(View.INVISIBLE);
168 }
Amith Yamasani655d0e22013-06-12 14:19:10 -0700169 }
170 };
Geoffrey Borggaard8135f3a2013-08-28 22:13:10 -0400171
172 @Override
173 public void onClick(View v) {
174 if (v == mOkButton) {
175 performPositiveButtonAction();
176 } else if (v == mCancelButton) {
177 setResult(RESULT_CANCELED);
178 finish();
179 }
180 }
Amith Yamasani655d0e22013-06-12 14:19:10 -0700181}