Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8135f3a9 authored by Geoffrey Borggaard's avatar Geoffrey Borggaard
Browse files

UX improvements to the restrictions PIN

As per Rachel.  Remove the title, change the hint text.
Don't make the dialog disappear after failed attempts.
Bug: 10542734

Change-Id: I1cae3d74bd4da06364626d63faf945f629cf6537
parent 6627e5b2
Loading
Loading
Loading
Loading
+51 −37
Original line number Diff line number Diff line
@@ -16,9 +16,7 @@

package com.android.internal.app;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.UserManager;
import android.text.Editable;
@@ -26,7 +24,8 @@ import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -38,14 +37,15 @@ import com.android.internal.R;
 * challenge for an existing PIN. The PIN is maintained by UserManager.
 */
public class RestrictionsPinActivity extends AlertActivity
        implements DialogInterface.OnClickListener, TextWatcher, OnEditorActionListener {
        implements OnClickListener, TextWatcher, OnEditorActionListener {

    protected UserManager mUserManager;
    protected boolean mHasRestrictionsPin;

    protected EditText mPinText;
    protected TextView mPinErrorMessage;
    protected TextView mPinMessage;
    private Button mOkButton;
    private Button mCancelButton;

    @Override
    public void onCreate(Bundle icicle) {
@@ -59,19 +59,20 @@ public class RestrictionsPinActivity extends AlertActivity

    protected void initUi() {
        AlertController.AlertParams ap = mAlertParams;
        ap.mTitle = getString(R.string.restr_pin_enter_pin);
        ap.mPositiveButtonText = getString(R.string.ok);
        ap.mNegativeButtonText = getString(R.string.cancel);
        ap.mPositiveButtonListener = this;
        ap.mNegativeButtonListener = this;
        ap.mTitle = getString(R.string.restr_pin_enter_admin_pin);
        LayoutInflater inflater =
                (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ap.mView = inflater.inflate(R.layout.restrictions_pin_challenge, null);

        mPinMessage = (TextView) ap.mView.findViewById(R.id.pin_message);
        mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
        mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
        mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
        mOkButton = (Button) ap.mView.findViewById(R.id.pin_ok_button);
        mCancelButton = (Button) ap.mView.findViewById(R.id.pin_cancel_button);

        mPinText.addTextChangedListener(this);

        mOkButton.setOnClickListener(this);
        mCancelButton.setOnClickListener(this);
    }

    protected boolean verifyingPin() {
@@ -84,8 +85,7 @@ public class RestrictionsPinActivity extends AlertActivity
        setPositiveButtonState(false);
        boolean hasPin = mUserManager.hasRestrictionsPin();
        if (hasPin) {
            mPinMessage.setVisibility(View.GONE);
            mPinErrorMessage.setVisibility(View.GONE);
            mPinErrorMessage.setVisibility(View.INVISIBLE);
            mPinText.setOnEditorActionListener(this);
            updatePinTimer(-1);
        } else if (verifyingPin()) {
@@ -94,39 +94,37 @@ public class RestrictionsPinActivity extends AlertActivity
        }
    }

    private void setPositiveButtonState(boolean enabled) {
        mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(enabled);
    protected void setPositiveButtonState(boolean enabled) {
        mOkButton.setEnabled(enabled);
    }

    private void updatePinTimer(int pinTimerMs) {
    private boolean updatePinTimer(int pinTimerMs) {
        if (pinTimerMs < 0) {
            pinTimerMs = mUserManager.checkRestrictionsPin(null);
        }
        boolean enableInput;
        if (pinTimerMs >= 200) {
            // Do the count down timer for less than a minute, otherwise just say try again later.
            if (pinTimerMs <= 60000) {
                final int seconds = (pinTimerMs + 200) / 1000;
                final String formatString = getResources().getQuantityString(
                        R.plurals.restr_pin_countdown,
                        seconds);
                mPinErrorMessage.setText(String.format(formatString, seconds));
            } else {
                mPinErrorMessage.setText(R.string.restr_pin_try_later);
            }
            enableInput = false;
            mPinErrorMessage.setVisibility(View.VISIBLE);
            mPinText.setEnabled(false);
            mPinText.setText("");
            setPositiveButtonState(false);
            mPinText.postDelayed(mCountdownRunnable, Math.min(1000, pinTimerMs));
        } else {
            mPinErrorMessage.setVisibility(View.INVISIBLE);
            mPinText.setEnabled(true);
            mPinText.setText("");
        }
    }

    public void onClick(DialogInterface dialog, int which) {
        setResult(RESULT_CANCELED);
        if (which == AlertDialog.BUTTON_POSITIVE) {
            performPositiveButtonAction();
        } else if (which == AlertDialog.BUTTON_NEGATIVE) {
            finish();
            enableInput = true;
            mPinErrorMessage.setText(R.string.restr_pin_incorrect);
        }
        mPinText.setEnabled(enableInput);
        setPositiveButtonState(enableInput);
        return enableInput;
    }

    protected void performPositiveButtonAction() {
@@ -135,7 +133,10 @@ public class RestrictionsPinActivity extends AlertActivity
            setResult(RESULT_OK);
            finish();
        } else if (result >= 0) {
            mPinErrorMessage.setText(R.string.restr_pin_incorrect);
            mPinErrorMessage.setVisibility(View.VISIBLE);
            updatePinTimer(result);
            mPinText.setText("");
        }
    }

@@ -161,7 +162,20 @@ public class RestrictionsPinActivity extends AlertActivity

    private Runnable mCountdownRunnable = new Runnable() {
        public void run() {
            updatePinTimer(-1);
            if (updatePinTimer(-1)) {
                // If we are no longer counting down, clear the message.
                mPinErrorMessage.setVisibility(View.INVISIBLE);
            }
        }
    };

    @Override
    public void onClick(View v) {
        if (v == mOkButton) {
            performPositiveButtonAction();
        } else if (v == mCancelButton) {
            setResult(RESULT_CANCELED);
            finish();
        }
    }
}
+1 −20
Original line number Diff line number Diff line
@@ -16,9 +16,7 @@

package com.android.internal.app;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.UserManager;
import android.text.Editable;
import android.text.TextUtils;
@@ -44,17 +42,13 @@ public class RestrictionsPinSetupActivity extends RestrictionsPinActivity {
        ap.mTitle = getString(R.string.restr_pin_enter_pin);
        ap.mPositiveButtonText = getString(R.string.ok);
        ap.mNegativeButtonText = getString(R.string.cancel);
        ap.mPositiveButtonListener = this;
        ap.mNegativeButtonListener = this;
        LayoutInflater inflater =
                (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ap.mView = inflater.inflate(R.layout.restrictions_pin_setup, null);

        mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
        mPinMessage = (TextView) ap.mView.findViewById(R.id.pin_message);
        mNewPinText = (EditText) ap.mView.findViewById(R.id.pin_new_text);
        mConfirmPinText = (EditText) ap.mView.findViewById(R.id.pin_confirm_text);
        mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
        mNewPinText.addTextChangedListener(this);
        mConfirmPinText.addTextChangedListener(this);

@@ -72,19 +66,7 @@ public class RestrictionsPinSetupActivity extends RestrictionsPinActivity {
        return false;
    }

    private void setPositiveButtonState(boolean enabled) {
        mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(enabled);
    }

    public void onClick(DialogInterface dialog, int which) {
        setResult(RESULT_CANCELED);
        if (which == AlertDialog.BUTTON_POSITIVE) {
            performPositiveButtonAction();
        } else if (which == AlertDialog.BUTTON_NEGATIVE) {
            finish();
        }
    }

    @Override
    protected void performPositiveButtonAction() {
        if (mHasRestrictionsPin) {
            int result = mUserManager.checkRestrictionsPin(mPinText.getText().toString());
@@ -115,7 +97,6 @@ public class RestrictionsPinSetupActivity extends RestrictionsPinActivity {
        boolean showError = !TextUtils.isEmpty(pin1) && !TextUtils.isEmpty(pin2);
        // TODO: Check recovery email address as well
        setPositiveButtonState(match);
        mPinErrorMessage.setVisibility((match || !showError) ? View.INVISIBLE : View.VISIBLE);
    }

    @Override
+56 −25
Original line number Diff line number Diff line
@@ -18,42 +18,73 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="48dp"
    android:layout_marginBottom="48dp"
    android:overScrollMode="ifContentScrolls">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dip"
        android:orientation="vertical">

        <TextView android:id="@+id/pin_message"
            style="?android:attr/textAppearanceMedium"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp"
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/restr_pin_create_pin"
            android:textColor="?android:attr/textColorSecondary" />
            android:padding="8dip"
            android:orientation="vertical">

            <EditText android:id="@+id/pin_text"
            style="?android:attr/textAppearanceMedium"
            android:layout_marginBottom="16dp"
                android:layout_marginLeft="8dip"
                android:layout_marginStart="8dip"
                android:layout_marginRight="8dip"
                android:layout_marginEnd="8dip"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
            android:hint="@string/restr_pin_enter_pin"
                android:inputType="numberPassword"
                android:textColor="?android:attr/textColorPrimary" />

            <TextView android:id="@+id/pin_error_message"
            style="?android:attr/textAppearanceSmall"
            android:layout_marginBottom="16dp"
                android:layout_marginTop="8dp"
                android:layout_marginBottom="8dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
            android:text="@string/restr_pin_error_doesnt_match"
            android:textColor="#FFFF0000" />

                android:text="@string/restr_pin_incorrect"
                android:gravity="center"/>
        </LinearLayout>

        <LinearLayout android:id="@+id/buttonPanel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="@dimen/alert_dialog_button_bar_height"
            android:orientation="vertical"
            android:divider="?android:attr/dividerHorizontal"
            android:showDividers="beginning"
            android:dividerPadding="0dip">
            <LinearLayout
                style="?android:attr/buttonBarStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layoutDirection="locale"
                android:measureWithLargestChild="true">
                <Button android:id="@+id/pin_cancel_button"
                    android:layout_width="wrap_content"
                    android:layout_gravity="start"
                    android:layout_weight="1"
                    android:maxLines="2"
                    android:minHeight="@dimen/alert_dialog_button_bar_height"
                    style="?android:attr/buttonBarButtonStyle"
                    android:textSize="14sp"
                    android:layout_height="wrap_content"
                    android:text="@string/cancel" />
                <Button android:id="@+id/pin_ok_button"
                    android:layout_width="wrap_content"
                    android:layout_gravity="end"
                    android:layout_weight="1"
                    android:maxLines="2"
                    style="?android:attr/buttonBarButtonStyle"
                    android:textSize="14sp"
                    android:minHeight="@dimen/alert_dialog_button_bar_height"
                    android:layout_height="wrap_content"
                    android:text="@string/ok" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</ScrollView>
+8 −2
Original line number Diff line number Diff line
@@ -4296,8 +4296,12 @@
    <!-- Print fail reason: unknown. [CHAR LIMIT=25] -->
    <string name="reason_unknown">unknown</string>

    <!-- PIN entry dialog title for entering the administrator PIN [CHAR LIMIT=none] -->
    <string name="restr_pin_enter_admin_pin">Enter administrator PIN</string>
    <!-- PIN entry dialog label/hint for PIN [CHAR LIMIT=none] -->
    <string name="restr_pin_enter_pin">Enter PIN</string>
    <!-- PIN entry dialog label/hint for incorrect PIN entry [CHAR LIMIT=none] -->
    <string name="restr_pin_incorrect">Incorrect</string>
    <!-- PIN entry dialog label/hint for old PIN [CHAR LIMIT=none] -->
    <string name="restr_pin_enter_old_pin">Current PIN</string>
    <!-- PIN entry dialog label for new PIN [CHAR LIMIT=none] -->
@@ -4313,9 +4317,11 @@
    <!-- PIN entry dialog countdown message for next chance to enter the PIN [CHAR LIMIT=none] -->
    <!-- Phrase describing a time duration using seconds [CHAR LIMIT=16] -->
    <plurals name="restr_pin_countdown">
        <item quantity="one">Incorrect PIN. Try again in 1 second.</item>
        <item quantity="other">Incorrect PIN. Try again in <xliff:g id="count">%d</xliff:g> seconds.</item>
        <item quantity="one">Try again in 1 second</item>
        <item quantity="other">Try again in <xliff:g id="count">%d</xliff:g> seconds</item>
    </plurals>
    <!-- PIN entry dialog tells the user to not enter a PIN for a while. [CHAR LIMIT=none] -->
    <string name="restr_pin_try_later">Try again later</string>

    <!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=35] -->
    <string name="transient_navigation_confirmation">Swipe edge of screen to reveal bar</string>
+5 −1
Original line number Diff line number Diff line
@@ -212,7 +212,8 @@
  <java-symbol type="id" name="sms_short_code_remember_undo_instruction" />
  <java-symbol type="id" name="breadcrumb_section" />
  <java-symbol type="id" name="action_bar_spinner" />
  <java-symbol type="id" name="pin_message" />
  <java-symbol type="id" name="pin_cancel_button" />
  <java-symbol type="id" name="pin_ok_button" />
  <java-symbol type="id" name="pin_text" />
  <java-symbol type="id" name="pin_new_text" />
  <java-symbol type="id" name="pin_confirm_text" />
@@ -870,7 +871,10 @@
  <java-symbol type="string" name="mediaSize_na_ledger" />
  <java-symbol type="string" name="mediaSize_na_tabloid" />
  <java-symbol type="string" name="reason_unknown" />
  <java-symbol type="string" name="restr_pin_enter_admin_pin" />
  <java-symbol type="string" name="restr_pin_enter_pin" />
  <java-symbol type="string" name="restr_pin_incorrect" />
  <java-symbol type="string" name="restr_pin_try_later" />
  <java-symbol type="string" name="write_fail_reason_cancelled" />
  <java-symbol type="string" name="write_fail_reason_cannot_write" />
  <java-symbol type="string" name="transient_navigation_confirmation" />