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

Commit cb9a7075 authored by Christine Franks's avatar Christine Franks Committed by Android (Google) Code Review
Browse files

Merge "Move logic for FR in demo mode out of Settings" into oc-dr1-dev

parents e09338a2 a09eb383
Loading
Loading
Loading
Loading
+18 −18
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -38,6 +38,7 @@ import android.os.UserManager;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.telephony.euicc.EuiccManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -54,7 +55,6 @@ import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmLockPattern;
import com.android.settings.widget.CarrierDemoPasswordDialogFragment;
import com.android.settingslib.RestrictedLockUtils;

import java.util.List;
@@ -69,8 +69,7 @@ import java.util.List;
 *
 * This is the initial screen.
 */
public class MasterClear extends OptionsMenuFragment
        implements CarrierDemoPasswordDialogFragment.Callback {
public class MasterClear extends OptionsMenuFragment {
    private static final String TAG = "MasterClear";

    private static final int KEYGUARD_REQUEST = 55;
@@ -137,15 +136,21 @@ public class MasterClear extends OptionsMenuFragment
     * If the user clicks to begin the reset sequence, we next require a
     * keyguard confirmation if the user has currently enabled one.  If there
     * is no keyguard available, we simply go to the final confirmation prompt.
     *
     * If the user is in demo mode, route to the demo mode app for confirmation.
     */
    private final Button.OnClickListener mInitiateListener = new Button.OnClickListener() {

        public void onClick(View v) {
            if ( Utils.isCarrierDemoUser(v.getContext())) {
                // Require the carrier password before displaying the final confirmation.
                final FragmentManager fm = getChildFragmentManager();
                if (fm != null && !fm.isDestroyed()) {
                    new CarrierDemoPasswordDialogFragment().show(fm, null /* tag */);
    @VisibleForTesting
    protected final Button.OnClickListener mInitiateListener = new Button.OnClickListener() {

        public void onClick(View view) {
            final Context context = view.getContext();
            if (Utils.isDemoUser(context)) {
                final String packageName = Utils.getDemoModePackageName(context);
                if (!TextUtils.isEmpty(packageName)) {
                    final Intent requestFactoryReset = new Intent()
                            .setPackage(packageName)
                            .setAction(Intent.ACTION_FACTORY_RESET);
                    context.startActivity(requestFactoryReset);
                }
            } else if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
                showFinalConfirmation();
@@ -153,11 +158,6 @@ public class MasterClear extends OptionsMenuFragment
        }
    };

    @Override
    public void onPasswordVerified() {
        showFinalConfirmation();
    }

    /**
     * In its initial state, the activity presents a button for the user to
     * click in order to initiate a confirmation sequence.  This method is
@@ -395,7 +395,7 @@ public class MasterClear extends OptionsMenuFragment
        final UserManager um = UserManager.get(context);
        final boolean disallow = !um.isAdminUser() || RestrictedLockUtils.hasBaseUserRestriction(
                context, UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId());
        if (disallow && !Utils.isCarrierDemoUser(context)) {
        if (disallow && !Utils.isDemoUser(context)) {
            return inflater.inflate(R.layout.master_clear_disallowed_screen, null);
        } else if (admin != null) {
            View view = inflater.inflate(R.layout.admin_support_details_empty_view, null);
+0 −1
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.oemlock.OemLockManager;
import android.service.persistentdata.PersistentDataBlockManager;
import android.view.LayoutInflater;
+8 −8
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.support.annotation.StringRes;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
@@ -1271,14 +1272,13 @@ public final class Utils extends com.android.settingslib.Utils {
        }
    }

    public static boolean isCarrierDemoUser(Context context) {
        final String carrierDemoModeSetting =
                context.getString(com.android.internal.R.string.config_carrierDemoModeSetting);
        return UserManager.isDeviceInDemoMode(context)
                && getUserManager(context).isDemoUser()
                && !TextUtils.isEmpty(carrierDemoModeSetting)
                && (Settings.Secure.getInt(context.getContentResolver(),
                        carrierDemoModeSetting, 0) == 1);
    public static boolean isDemoUser(Context context) {
        return UserManager.isDeviceInDemoMode(context) && getUserManager(context).isDemoUser();
    }

    public static String getDemoModePackageName(Context context) {
        return context.getResources().getString(
                com.android.internal.R.string.config_demoModePackage);
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ public class FactoryResetPreferenceController extends PreferenceController {
    /** Hide "Factory reset" settings for secondary users, except demo users. */
    @Override
    public boolean isAvailable() {
        return mUm.isAdminUser() || Utils.isCarrierDemoUser(mContext);
        return mUm.isAdminUser() || Utils.isDemoUser(mContext);
    }

    @Override
+0 −144
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.settings.widget;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.HexDump;
import com.android.settings.R;

import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class CarrierDemoPasswordDialogFragment extends InstrumentedDialogFragment {

    private static final String TAG = "CarrierDemoPasswordDF";

    private MessageDigest mMessageDigest;

    public CarrierDemoPasswordDialogFragment() {
        try {
            mMessageDigest = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "Unable to verify demo mode password", e);
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final AlertDialog dialog = new AlertDialog.Builder(getContext())
                .setPositiveButton(R.string.retail_demo_reset_next,
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        final Fragment parentFragment = getParentFragment();
                        if (parentFragment instanceof Callback
                                && which == DialogInterface.BUTTON_POSITIVE) {
                            ((Callback) parentFragment).onPasswordVerified();
                        }
                    }
                })
                .setNegativeButton(android.R.string.cancel, null)
                .setMessage(R.string.retail_demo_reset_message)
                .setTitle(R.string.retail_demo_reset_title)
                .create();

        final Context context = dialog.getContext();
        final EditText passwordField = new EditText(context);
        passwordField.setSingleLine();
        passwordField.setInputType(InputType.TYPE_CLASS_TEXT
                | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        passwordField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // no-op
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                verifyPassword(dialog, passwordField.getText().toString());
            }

            @Override
            public void afterTextChanged(Editable s) {
                // no-op
            }
        });

        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialogInterface) {
                verifyPassword(dialog, passwordField.getText().toString());
                passwordField.requestFocus();
                final InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
                        Context.INPUT_METHOD_SERVICE);
                imm.showSoftInput(passwordField, InputMethodManager.SHOW_IMPLICIT);
            }
        });
        dialog.setCanceledOnTouchOutside(false);

        final TypedArray a = context.obtainStyledAttributes(
                new int[] { android.R.attr.dialogPreferredPadding });
        final int sidePadding = a.getDimensionPixelSize(0, 0);
        dialog.setView(passwordField, sidePadding, 0, sidePadding, 0);
        a.recycle();

        return dialog;
    }

    private void verifyPassword(AlertDialog dialog, String input) {
        final Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
        if (mMessageDigest == null || TextUtils.isEmpty(input)) {
            positiveButton.setEnabled(false);
            return;
        }
        final String passwordHash = getContext().getString(
                com.android.internal.R.string.config_carrierDemoModePassword);
        if (passwordHash == null || TextUtils.isEmpty(passwordHash)) {
            // This device does not support carrier demo mode.
            return;
        }
        final byte[] inputDigest = mMessageDigest.digest(input.getBytes());
        final String inputHash = HexDump.toHexString(inputDigest, 0, inputDigest.length, false);
        positiveButton.setEnabled(TextUtils.equals(passwordHash, inputHash));
    }

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.CARRIER_DEMO_MODE_PASSWORD;
    }

    public interface Callback {
        void onPasswordVerified();
    }
}
Loading