blob: f8ce10873a50a4ae902edb05936b1874120e7c18 [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
19import android.app.AlertDialog;
20import android.content.Context;
21import android.content.DialogInterface;
22import android.os.Bundle;
23import android.os.UserManager;
24import android.text.Editable;
25import android.text.TextWatcher;
26import android.view.KeyEvent;
27import android.view.LayoutInflater;
28import android.view.View;
Amith Yamasani1a7472e2013-07-02 11:17:30 -070029import android.view.WindowManager;
Amith Yamasani655d0e22013-06-12 14:19:10 -070030import android.widget.EditText;
31import android.widget.TextView;
32import android.widget.TextView.OnEditorActionListener;
33
34import com.android.internal.R;
35
36/**
37 * This activity is launched by Settings and other apps to either create a new PIN or
38 * challenge for an existing PIN. The PIN is maintained by UserManager.
39 */
40public class RestrictionsPinActivity extends AlertActivity
41 implements DialogInterface.OnClickListener, TextWatcher, OnEditorActionListener {
42
Amith Yamasani1a7472e2013-07-02 11:17:30 -070043 protected UserManager mUserManager;
44 protected boolean mHasRestrictionsPin;
Amith Yamasani655d0e22013-06-12 14:19:10 -070045
Amith Yamasani1a7472e2013-07-02 11:17:30 -070046 protected EditText mPinText;
47 protected TextView mPinErrorMessage;
48 protected TextView mPinMessage;
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);
55 mHasRestrictionsPin = mUserManager.hasRestrictionsPin();
56 initUi();
57 setupAlert();
58 }
59
60 protected void initUi() {
Amith Yamasani655d0e22013-06-12 14:19:10 -070061 AlertController.AlertParams ap = mAlertParams;
62 ap.mTitle = getString(R.string.restr_pin_enter_pin);
63 ap.mPositiveButtonText = getString(R.string.ok);
64 ap.mNegativeButtonText = getString(R.string.cancel);
65 ap.mPositiveButtonListener = this;
66 ap.mNegativeButtonListener = this;
67 LayoutInflater inflater =
68 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Amith Yamasani1a7472e2013-07-02 11:17:30 -070069 ap.mView = inflater.inflate(R.layout.restrictions_pin_challenge, null);
Amith Yamasani655d0e22013-06-12 14:19:10 -070070
71 mPinMessage = (TextView) ap.mView.findViewById(R.id.pin_message);
Amith Yamasani1a7472e2013-07-02 11:17:30 -070072 mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
Amith Yamasani655d0e22013-06-12 14:19:10 -070073 mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
Amith Yamasani1a7472e2013-07-02 11:17:30 -070074 mPinText.addTextChangedListener(this);
Amith Yamasani655d0e22013-06-12 14:19:10 -070075 }
76
77 protected boolean verifyingPin() {
78 return true;
79 }
80
81 public void onResume() {
82 super.onResume();
83
84 setPositiveButtonState(false);
85 boolean hasPin = mUserManager.hasRestrictionsPin();
Amith Yamasani1a7472e2013-07-02 11:17:30 -070086 if (hasPin) {
87 mPinMessage.setVisibility(View.GONE);
88 mPinErrorMessage.setVisibility(View.GONE);
89 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
97 private void setPositiveButtonState(boolean enabled) {
98 mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(enabled);
99 }
100
101 private void updatePinTimer(int pinTimerMs) {
102 if (pinTimerMs < 0) {
103 pinTimerMs = mUserManager.checkRestrictionsPin(null);
104 }
105 if (pinTimerMs >= 200) {
106 final int seconds = (pinTimerMs + 200) / 1000;
107 final String formatString = getResources().getQuantityString(
108 R.plurals.restr_pin_countdown,
109 seconds);
110 mPinErrorMessage.setText(String.format(formatString, seconds));
111 mPinErrorMessage.setVisibility(View.VISIBLE);
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700112 mPinText.setEnabled(false);
113 mPinText.setText("");
Amith Yamasani655d0e22013-06-12 14:19:10 -0700114 setPositiveButtonState(false);
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700115 mPinText.postDelayed(mCountdownRunnable, Math.min(1000, pinTimerMs));
Amith Yamasani655d0e22013-06-12 14:19:10 -0700116 } else {
117 mPinErrorMessage.setVisibility(View.INVISIBLE);
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700118 mPinText.setEnabled(true);
119 mPinText.setText("");
Amith Yamasani655d0e22013-06-12 14:19:10 -0700120 }
121 }
122
123 public void onClick(DialogInterface dialog, int which) {
124 setResult(RESULT_CANCELED);
125 if (which == AlertDialog.BUTTON_POSITIVE) {
126 performPositiveButtonAction();
127 } else if (which == AlertDialog.BUTTON_NEGATIVE) {
128 finish();
129 }
130 }
131
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700132 protected void performPositiveButtonAction() {
133 int result = mUserManager.checkRestrictionsPin(mPinText.getText().toString());
134 if (result == UserManager.PIN_VERIFICATION_SUCCESS) {
135 setResult(RESULT_OK);
136 finish();
137 } else if (result >= 0) {
138 updatePinTimer(result);
Amith Yamasani655d0e22013-06-12 14:19:10 -0700139 }
140 }
141
142 @Override
143 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
144 }
145
146 @Override
147 public void onTextChanged(CharSequence s, int start, int before, int count) {
Amith Yamasani1a7472e2013-07-02 11:17:30 -0700148 CharSequence pin = mPinText.getText();
149 setPositiveButtonState(pin != null && pin.length() >= 4);
Amith Yamasani655d0e22013-06-12 14:19:10 -0700150 }
151
152 @Override
153 public void afterTextChanged(Editable s) {
154 }
155
156 @Override
157 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
158 performPositiveButtonAction();
159 return true;
160 }
161
162 private Runnable mCountdownRunnable = new Runnable() {
163 public void run() {
164 updatePinTimer(-1);
165 }
166 };
167}