Fragmentize "Factory reset" setting screen.
Split the screen into 2 fragments.
Bug: 3148480
diff --git a/proguard.flags b/proguard.flags
index 457972c..7cd46e7 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -7,3 +7,6 @@
-keep class com.android.settings.bluetooth.*
-keep class com.android.settings.applications.*
-keep class com.android.settings.inputmethod.*
+-keep class com.android.settings.MasterClear
+-keep class com.android.settings.MasterClearConfirm
+
diff --git a/res/layout/master_clear_primary.xml b/res/layout/master_clear.xml
similarity index 66%
rename from res/layout/master_clear_primary.xml
rename to res/layout/master_clear.xml
index dd25900..16222d3 100644
--- a/res/layout/master_clear_primary.xml
+++ b/res/layout/master_clear.xml
@@ -1,29 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright (C) 2008 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.
-*/
+<!-- Copyright (C) 2010 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.
-->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/info_layout">
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ >
<ScrollView
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="0dip"
+ android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
+ android:layout_marginTop="12dp"
android:layout_weight="1">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -42,13 +44,14 @@
<CheckBox android:id="@+id/erase_external"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="top"
+ android:layout_gravity="center_vertical"
android:paddingRight="8dp"
android:focusable="false"
android:clickable="false"
android:duplicateParentState="true" />
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
@@ -70,7 +73,8 @@
android:id="@+id/initiate_master_clear"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip"
- android:layout_width="150dip"
+ android:layout_marginBottom="12dip"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/master_clear_button_text"
android:gravity="center" />
diff --git a/res/layout/master_clear_confirm.xml b/res/layout/master_clear_confirm.xml
new file mode 100644
index 0000000..0599b10
--- /dev/null
+++ b/res/layout/master_clear_confirm.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
+ android:layout_marginTop="12dp"
+ android:textSize="20sp"
+ android:text="@string/master_clear_final_desc" />
+
+ <Button android:id="@+id/execute_master_clear"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="40dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/master_clear_final_button_text"
+ android:gravity="center" />
+
+</LinearLayout>
diff --git a/res/layout/master_clear_final.xml b/res/layout/master_clear_final.xml
deleted file mode 100644
index 8de789a..0000000
--- a/res/layout/master_clear_final.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright (C) 2008 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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/info_layout">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="20sp"
- android:text="@string/master_clear_final_desc" />
-
- <Button android:id="@+id/execute_master_clear"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="40dip"
- android:layout_width="150dip"
- android:layout_height="wrap_content"
- android:text="@string/master_clear_final_button_text"
- android:gravity="center" />
-
-</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 53ddc4b..2d96ff6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1608,6 +1608,8 @@
<string name="master_clear_gesture_explanation">You must draw your unlock pattern to confirm a factory data reset.</string>
<!-- Master clear failed message -->
<string name="master_clear_failed">No reset was performed because the System Clear service is not available.</string>
+ <!-- Master clear confirmation screen title [CHAR LIMIT=30] -->
+ <string name="master_clear_confirm_title">Confirm reset</string>
<!-- Media Format -->
<!-- SD card & phone storage settings screen, setting option name under Internal phone storage heading [CHAR LIMIT=25] -->
diff --git a/res/xml/privacy_settings.xml b/res/xml/privacy_settings.xml
index 742c621..86fc306 100644
--- a/res/xml/privacy_settings.xml
+++ b/res/xml/privacy_settings.xml
@@ -33,15 +33,11 @@
</PreferenceCategory>
<PreferenceCategory
- android:title="@string/personal_data_section_title">
+ android:title="@string/personal_data_section_title"/>
<!-- Factory reset -->
- <PreferenceScreen
- android:title="@string/master_clear_title"
- android:summary="@string/master_clear_summary">
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.settings"
- android:targetClass="com.android.settings.MasterClear" />
- </PreferenceScreen>
- </PreferenceCategory>
+ <PreferenceScreen
+ android:title="@string/master_clear_title"
+ android:summary="@string/master_clear_summary"
+ android:fragment="com.android.settings.MasterClear" />
</PreferenceScreen>
diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java
index abcfc05..d31fe3b 100644
--- a/src/com/android/settings/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/ChooseLockSettingsHelper.java
@@ -16,21 +16,28 @@
package com.android.settings;
+import com.android.internal.widget.LockPatternUtils;
+
import android.app.Activity;
+import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;
-import com.android.internal.widget.LockPatternUtils;
-
public class ChooseLockSettingsHelper {
private LockPatternUtils mLockPatternUtils;
private Activity mActivity;
+ private Fragment mFragment;
public ChooseLockSettingsHelper(Activity activity) {
mActivity = activity;
mLockPatternUtils = new LockPatternUtils(activity);
}
+ public ChooseLockSettingsHelper(Activity activity, Fragment fragment) {
+ this(activity);
+ mFragment = fragment;
+ }
+
public LockPatternUtils utils() {
return mLockPatternUtils;
}
@@ -76,7 +83,11 @@
intent.putExtra(ConfirmLockPattern.HEADER_TEXT, message);
intent.putExtra(ConfirmLockPattern.FOOTER_TEXT, details);
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
- mActivity.startActivityForResult(intent, request);
+ if (mFragment != null) {
+ mFragment.startActivityForResult(intent, request);
+ } else {
+ mActivity.startActivityForResult(intent, request);
+ }
return true;
}
@@ -89,7 +100,11 @@
if (!mLockPatternUtils.isLockPasswordEnabled()) return false;
final Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPassword");
- mActivity.startActivityForResult(intent, request);
+ if (mFragment != null) {
+ mFragment.startActivityForResult(intent, request);
+ } else {
+ mActivity.startActivityForResult(intent, request);
+ }
return true;
}
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index e653d90..a2ef7f4 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -16,14 +16,18 @@
package com.android.settings;
-import com.android.internal.os.storage.ExternalStorageFormatter;
-import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
import android.app.Activity;
+import android.app.Fragment;
import android.content.Intent;
+import android.content.res.Resources;
import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
@@ -34,44 +38,20 @@
* has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING
* ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is
* locked, et cetera, then the confirmation sequence is abandoned.
+ *
+ * This is the initial screen.
*/
-public class MasterClear extends Activity {
+public class MasterClear extends Fragment {
private static final int KEYGUARD_REQUEST = 55;
- private LayoutInflater mInflater;
- private LockPatternUtils mLockUtils;
+ static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
- private View mInitialView;
+ private View mContentView;
private Button mInitiateButton;
private View mExternalStorageContainer;
private CheckBox mExternalStorage;
- private View mFinalView;
- private Button mFinalButton;
-
- /**
- * The user has gone through the multiple confirmation, so now we go ahead
- * and invoke the Checkin Service to reset the device to its factory-default
- * state (rebooting in the process).
- */
- private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
- public void onClick(View v) {
- if (Utils.isMonkeyRunning()) {
- return;
- }
-
- if (mExternalStorage.isChecked()) {
- Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
- intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
- startService(intent);
- } else {
- sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
- // Intent handling is asynchronous -- assume it will happen soon.
- }
- }
- };
-
/**
* Keyguard validation is run using the standard {@link ConfirmLockPattern}
* component as a subactivity
@@ -79,14 +59,15 @@
* @return true if confirmation launched
*/
private boolean runKeyguardConfirmation(int request) {
- return new ChooseLockSettingsHelper(this)
+ Resources res = getActivity().getResources();
+ return new ChooseLockSettingsHelper(getActivity(), this)
.launchConfirmationActivity(request,
- getText(R.string.master_clear_gesture_prompt),
- getText(R.string.master_clear_gesture_explanation));
+ res.getText(R.string.master_clear_gesture_prompt),
+ res.getText(R.string.master_clear_gesture_explanation));
}
@Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != KEYGUARD_REQUEST) {
@@ -96,40 +77,33 @@
// If the user entered a valid keyguard trace, present the final
// confirmation prompt; otherwise, go back to the initial state.
if (resultCode == Activity.RESULT_OK) {
- establishFinalConfirmationState();
- } else if (resultCode == Activity.RESULT_CANCELED) {
- finish();
+ showFinalConfirmation();
} else {
establishInitialState();
}
}
+ private void showFinalConfirmation() {
+ Preference preference = new Preference(getActivity());
+ preference.setFragment(MasterClearConfirm.class.getName());
+ preference.setTitle(R.string.master_clear_confirm_title);
+ preference.getExtras().putBoolean(ERASE_EXTERNAL_EXTRA, mExternalStorage.isChecked());
+ ((PreferenceActivity) getActivity()).onPreferenceStartFragment(null, preference);
+ }
+
/**
* 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.
*/
private Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
- public void onClick(View v) {
- if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
- establishFinalConfirmationState();
- }
+
+ public void onClick(View v) {
+ if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
+ showFinalConfirmation();
}
- };
-
- /**
- * Configure the UI for the final confirmation interaction
- */
- private void establishFinalConfirmationState() {
- if (mFinalView == null) {
- mFinalView = mInflater.inflate(R.layout.master_clear_final, null);
- mFinalButton =
- (Button) mFinalView.findViewById(R.id.execute_master_clear);
- mFinalButton.setOnClickListener(mFinalClickListener);
}
-
- setContentView(mFinalView);
- }
+ };
/**
* In its initial state, the activity presents a button for the user to
@@ -144,48 +118,25 @@
* to change contents.
*/
private void establishInitialState() {
- if (mInitialView == null) {
- mInitialView = mInflater.inflate(R.layout.master_clear_primary, null);
- mInitiateButton =
- (Button) mInitialView.findViewById(R.id.initiate_master_clear);
- mInitiateButton.setOnClickListener(mInitiateListener);
- mExternalStorageContainer =
- mInitialView.findViewById(R.id.erase_external_container);
- mExternalStorage =
- (CheckBox) mInitialView.findViewById(R.id.erase_external);
- mExternalStorageContainer.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mExternalStorage.toggle();
- }
- });
- }
+ mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_master_clear);
+ mInitiateButton.setOnClickListener(mInitiateListener);
+ mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
+ mExternalStorage = (CheckBox) mContentView.findViewById(R.id.erase_external);
- setContentView(mInitialView);
+ mExternalStorageContainer.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ mExternalStorage.toggle();
+ }
+ });
}
@Override
- protected void onCreate(Bundle savedState) {
- super.onCreate(savedState);
-
- mInitialView = null;
- mFinalView = null;
- mInflater = LayoutInflater.from(this);
- mLockUtils = new LockPatternUtils(this);
-
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mContentView = inflater.inflate(R.layout.master_clear, null);
establishInitialState();
- }
-
- /** Abandon all progress through the confirmation sequence by returning
- * to the initial view any time the activity is interrupted (e.g. by
- * idle timeout).
- */
- @Override
- public void onPause() {
- super.onPause();
-
- if (!isFinishing()) {
- establishInitialState();
- }
+ return mContentView;
}
}
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
new file mode 100644
index 0000000..9c15c73
--- /dev/null
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 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;
+
+import com.android.internal.os.storage.ExternalStorageFormatter;
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CheckBox;
+
+/**
+ * Confirm and execute a reset of the device to a clean "just out of the box"
+ * state. Multiple confirmations are required: first, a general "are you sure
+ * you want to do this?" prompt, followed by a keyguard pattern trace if the user
+ * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING
+ * ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is
+ * locked, et cetera, then the confirmation sequence is abandoned.
+ *
+ * This is the confirmation screen.
+ */
+public class MasterClearConfirm extends Fragment {
+
+ private View mContentView;
+ private boolean mEraseSdCard;
+ private Button mFinalButton;
+
+ /**
+ * The user has gone through the multiple confirmation, so now we go ahead
+ * and invoke the Checkin Service to reset the device to its factory-default
+ * state (rebooting in the process).
+ */
+ private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
+
+ public void onClick(View v) {
+ if (Utils.isMonkeyRunning()) {
+ return;
+ }
+
+ if (mEraseSdCard) {
+ Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
+ intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
+ getActivity().startService(intent);
+ } else {
+ getActivity().sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
+ // Intent handling is asynchronous -- assume it will happen soon.
+ }
+ }
+ };
+
+ /**
+ * Configure the UI for the final confirmation interaction
+ */
+ private void establishFinalConfirmationState() {
+ mFinalButton = (Button) mContentView.findViewById(R.id.execute_master_clear);
+ mFinalButton.setOnClickListener(mFinalClickListener);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mContentView = inflater.inflate(R.layout.master_clear_confirm, null);
+ establishFinalConfirmationState();
+ return mContentView;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Bundle args = getArguments();
+ mEraseSdCard = args != null ? args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA) : false;
+ }
+}
diff --git a/src/com/android/settings/PrivacySettings.java b/src/com/android/settings/PrivacySettings.java
index 826c9cf..3f62f19 100644
--- a/src/com/android/settings/PrivacySettings.java
+++ b/src/com/android/settings/PrivacySettings.java
@@ -98,7 +98,7 @@
}
}
- return false;
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
}
private void showEraseBackupDialog() {