Move logic for FR in demo mode out of Settings

Bug: 62712426
Test: make \
ROBOTEST_FILTER="(MasterClearTest|FactoryResetPreferenceControllerTest
|UtilsTest)" \
RunSettingsRoboTests -j100
Change-Id: I5e287c3d4a6a7050bda78187c52aec19e90b50bc
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index fe0111b..1bdd6f4 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -22,7 +22,7 @@
 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.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 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 @@
  *
  * 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 @@
      * 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() {
+    @VisibleForTesting
+    protected 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 */);
+        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 @@
         }
     };
 
-    @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 @@
         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);
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index 7a85dbe..39bf01a 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -24,7 +24,6 @@
 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;
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 440debc..9b3414c 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -77,6 +77,7 @@
 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;
@@ -1240,14 +1241,13 @@
         }
     }
 
-    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);
     }
 
     /**
diff --git a/src/com/android/settings/system/FactoryResetPreferenceController.java b/src/com/android/settings/system/FactoryResetPreferenceController.java
index 69eef2a..7e9773b 100644
--- a/src/com/android/settings/system/FactoryResetPreferenceController.java
+++ b/src/com/android/settings/system/FactoryResetPreferenceController.java
@@ -47,7 +47,7 @@
     /** 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
diff --git a/src/com/android/settings/widget/CarrierDemoPasswordDialogFragment.java b/src/com/android/settings/widget/CarrierDemoPasswordDialogFragment.java
deleted file mode 100644
index 8482b9f..0000000
--- a/src/com/android/settings/widget/CarrierDemoPasswordDialogFragment.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index 8e8578f..edad391 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -27,6 +27,7 @@
 import android.app.Activity;
 import android.app.Fragment;
 import android.content.ContentResolver;
+import android.content.Intent;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.view.LayoutInflater;
@@ -36,6 +37,8 @@
 import android.widget.ScrollView;
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.ShadowUtils;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,11 +46,10 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowActivity;
 
-
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class MasterClearTest {
@@ -167,6 +169,22 @@
         assertThat(mMasterClear.hasReachedBottom(mScrollView)).isTrue();
     }
 
+    @Test
+    @Config(shadows = { ShadowUtils.class, SettingsShadowResources.class })
+    public void testInitiateMasterClear_inDemoMode_sendsIntent() {
+        SettingsShadowResources.overrideResource(
+            com.android.internal.R.string.config_demoModePackage, "package");
+
+        ShadowUtils.setIsDemoUser(true);
+
+        mMasterClear.mInitiateListener.onClick(
+                mContentView.findViewById(R.id.initiate_master_clear));
+        final Intent intent = mShadowActivity.getNextStartedActivity();
+        assertThat(Intent.ACTION_FACTORY_RESET).isEqualTo(intent.getAction());
+        final String packageName = Utils.getDemoModePackageName(RuntimeEnvironment.application);
+        assertThat(packageName).isEqualTo(intent.getPackage());
+    }
+
     private void initScrollView(int height, int scrollY, int childBottom) {
         when(mScrollView.getHeight()).thenReturn(height);
         when(mScrollView.getScrollY()).thenReturn(scrollY);
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index d85464d..7531ce1 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -16,15 +16,18 @@
 import android.net.Network;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
+import android.os.UserManager;
 import android.os.storage.DiskInfo;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.provider.Settings;
 import android.text.SpannableStringBuilder;
 import android.text.format.DateUtils;
 import android.text.style.TtsSpan;
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
+import com.android.settings.testutils.shadow.ShadowSecureSettings;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
index b9c34f3..7310ae0 100644
--- a/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
@@ -22,7 +22,6 @@
 import android.accounts.AccountManager;
 import android.content.Context;
 import android.os.UserManager;
-import android.provider.Settings;
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
@@ -76,21 +75,16 @@
     @Config(shadows = { ShadowSecureSettings.class, ShadowUtils.class })
     public void isAvailable_nonSystemUser() {
         when(mUserManager.isAdminUser()).thenReturn(false);
-        ShadowUtils.setIsCarrierDemoUser(false);
+        ShadowUtils.setIsDemoUser(false);
 
         assertThat(mController.isAvailable()).isFalse();
     }
 
     @Test
     @Config(shadows = { ShadowSecureSettings.class, ShadowUtils.class })
-    public void isAvailable_carrierDemoUser() {
+    public void isAvailable_demoUser() {
         when(mUserManager.isAdminUser()).thenReturn(false);
-        ShadowUtils.setIsCarrierDemoUser(true);
-
-        final String carrierDemoModeSetting = "carrier_demo_mode";
-        when(mContext.getString(com.android.internal.R.string.config_carrierDemoModeSetting))
-                .thenReturn(carrierDemoModeSetting);
-        Settings.Secure.putInt(null, carrierDemoModeSetting, 1);
+        ShadowUtils.setIsDemoUser(true);
 
         assertThat(mController.isAvailable()).isTrue();
     }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
index 854392f..82f53a2 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.testutils.shadow;
 
+import android.content.ComponentName;
 import android.content.Context;
 
 import com.android.settings.Utils;
@@ -28,8 +29,8 @@
 public class ShadowUtils {
 
     private static IFingerprintManager sFingerprintManager = null;
-    private static boolean sIsCarrierDemoUser;
     private static boolean sIsUserAMonkey;
+    private static boolean sIsDemoUser;
 
     @Implementation
     public static int enforceSameOwner(Context context, int userId) {
@@ -47,8 +48,8 @@
 
     public static void reset() {
         sFingerprintManager = null;
-        sIsCarrierDemoUser = false;
         sIsUserAMonkey = false;
+        sIsDemoUser = false;
     }
 
     @Implementation
@@ -56,8 +57,8 @@
         return true;
     }
 
-    public static void setIsCarrierDemoUser(boolean isCarrierDemoUser) {
-        sIsCarrierDemoUser = isCarrierDemoUser;
+    public static void setIsDemoUser(boolean isDemoUser) {
+        sIsDemoUser = isDemoUser;
     }
 
     public static void setIsUserAMonkey(boolean isUserAMonkey) {
@@ -66,8 +67,8 @@
 
 
     @Implementation
-    public static boolean isCarrierDemoUser(Context context) {
-        return sIsCarrierDemoUser;
+    public static boolean isDemoUser(Context context) {
+        return sIsDemoUser;
     }
 
     /**