Change reset page to be SUW style

The factory reset page and the reset confirmation page is too old to
follow the style of Setup Wizard design. To change the layout and apply
the style for textviews and header.

Bug: 73738836
Test: make -j SettingsRoboTests RunSettingsRoboTests
Change-Id: I1ee3d09e1ef9cac8e25c60a566363d4f7d537eeb
This commit is contained in:
felkachang
2018-03-29 12:08:20 +08:00
committed by Fan Zhang
parent 3600c03392
commit a6cec47326
10 changed files with 272 additions and 179 deletions

View File

@@ -0,0 +1,31 @@
<!--
Copyright (C) 2018 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorAccent">
<path
android:fillColor="#FF000000"
android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z"/>
<path
android:fillColor="#FF000000"
android:pathData="M9,8h2v9h-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M13,8h2v9h-2z"/>
</vector>

View File

@@ -14,122 +14,125 @@
limitations under the License. limitations under the License.
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <com.android.setupwizardlib.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical"
android:theme="@style/SuwThemeGlifV3.Light"
android:icon="@drawable/ic_delete_accent"
app:suwHeaderText="@string/master_clear_title">
<ScrollView <ScrollView
android:id="@+id/master_clear_scrollview" android:id="@+id/master_clear_scrollview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dip" android:layout_height="match_parent"
android:layout_marginStart="@dimen/reset_master_clear_margin_start" android:layout_marginStart="@dimen/reset_master_clear_margin_start"
android:layout_marginEnd="@dimen/reset_master_clear_margin_end" android:layout_marginEnd="@dimen/reset_master_clear_margin_end">
android:layout_marginTop="12dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:id="@+id/master_clear_container" android:id="@+id/master_clear_container"
style="@style/SuwContentFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="@style/master_clear_item_label" android:text="@string/master_clear_desc"/>
android:includeFontPadding="false" <TextView
android:text="@string/master_clear_desc" /> android:id="@+id/also_erases_external"
<TextView android:id="@+id/also_erases_external" style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="@style/master_clear_item_label"
android:includeFontPadding="false"
android:visibility="gone" android:visibility="gone"
android:text="@string/master_clear_desc_also_erases_external" /> android:text="@string/master_clear_desc_also_erases_external"/>
<TextView android:id="@+id/also_erases_esim" <TextView
android:id="@+id/also_erases_esim"
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="@style/master_clear_item_label"
android:includeFontPadding="false"
android:visibility="gone" android:visibility="gone"
android:text="@string/master_clear_desc_also_erases_esim" /> android:text="@string/master_clear_desc_also_erases_esim"/>
<TextView android:id="@+id/accounts_label" <TextView
android:id="@+id/accounts_label"
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="@style/master_clear_item_label"
android:visibility="gone" android:visibility="gone"
android:text="@string/master_clear_accounts" /> android:text="@string/master_clear_accounts"/>
<LinearLayout android:id="@+id/accounts" <LinearLayout
android:layout_width="wrap_content" android:id="@+id/accounts"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:orientation="vertical" android:layout_height="wrap_content"
android:visibility="gone"> android:orientation="vertical"
android:visibility="gone">
<!-- Do not add any children here as they will be removed in the MasterClear.java <!-- Do not add any children here as they will be removed in the MasterClear.java
code. A list of accounts will be inserted programmatically. --> code. A list of accounts will be inserted programmatically. -->
</LinearLayout> </LinearLayout>
<TextView android:id="@+id/other_users_present" <TextView
android:id="@+id/other_users_present"
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone" android:visibility="gone"
android:textSize="18sp" android:text="@string/master_clear_other_users_present"/>
android:text="@string/master_clear_other_users_present" /> <TextView
<TextView android:id="@+id/no_cancel_mobile_plan" android:id="@+id/no_cancel_mobile_plan"
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone" android:visibility="gone"
android:textSize="18sp" android:text="@string/master_clear_desc_no_cancel_mobile_plan"/>
android:text="@string/master_clear_desc_no_cancel_mobile_plan" /> <TextView
<TextView android:id="@+id/erase_external_option_text" android:id="@+id/erase_external_option_text"
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="18sp" android:text="@string/master_clear_desc_erase_external_storage"/>
android:text="@string/master_clear_desc_erase_external_storage" /> <LinearLayout
<LinearLayout android:id="@+id/erase_external_container" android:id="@+id/erase_external_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="true"
android:clickable="true">
<CheckBox
android:id="@+id/erase_external"
style="@style/SuwCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:clickable="false"
android:duplicateParentState="true"/>
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:layout_gravity="center_vertical"
android:focusable="true" android:orientation="vertical">
android:clickable="true">
<CheckBox android:id="@+id/erase_external"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingEnd="@dimen/reset_checkbox_padding_end"
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 <TextView
style="@style/TextAppearance.SuwGlifItemTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="@dimen/reset_checkbox_title_padding_top" android:text="@string/erase_external_storage"/>
android:textSize="@dimen/reset_checkbox_title_text_size"
android:text="@string/erase_external_storage" />
<TextView <TextView
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="@dimen/reset_checkbox_summary_padding_top" android:text="@string/erase_external_storage_description"/>
android:textSize="@dimen/reset_checkbox_summary_text_size"
android:text="@string/erase_external_storage_description" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<include layout="@layout/reset_esim_checkbox" <include
android:layout_marginTop="40dp" layout="@layout/reset_esim_checkbox"
android:id="@+id/erase_esim_container" android:layout_marginTop="40dp"
android:layout_width="match_parent" android:id="@+id/erase_esim_container"
android:layout_height="wrap_content" /> android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
<Button </com.android.setupwizardlib.GlifLayout>
android:id="@+id/initiate_master_clear"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip"
android:layout_marginBottom="12dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/master_clear_button_text"
android:gravity="center" />
</LinearLayout>

View File

@@ -20,8 +20,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingStart="16dp" style="@style/SuwDescription.Glif" >
android:paddingEnd="16dp">
<ImageView <ImageView
android:id="@android:id/icon" android:id="@android:id/icon"
android:layout_width="56dp" android:layout_width="56dp"
@@ -31,6 +30,6 @@
android:id="@android:id/title" android:id="@android:id/title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="18sp"/> style="@style/TextAppearance.SuwGlifItemSummary"/>
</LinearLayout> </LinearLayout>

View File

@@ -4,37 +4,37 @@
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <com.android.setupwizardlib.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
> android:theme="@style/SuwThemeGlifV3.Light"
android:id="@+id/setup_wizard_layout"
android:icon="@drawable/ic_delete_accent"
app:suwHeaderText="@string/master_clear_confirm_title">
<TextView <LinearLayout
android:id="@+id/master_clear_confirm" style="@style/SuwContentFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:orientation="vertical">
android:layout_marginEnd="12dp"
android:layout_marginTop="12dp"
android:textSize="20sp"
android:text="@string/master_clear_final_desc" />
<Button android:id="@+id/execute_master_clear" <TextView
android:layout_gravity="center_horizontal" android:id="@+id/master_clear_confirm"
android:layout_marginTop="40dip" style="@style/SuwItemTitle.GlifDescription"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/master_clear_final_button_text" android:text="@string/master_clear_final_desc"/>
android:gravity="center" /> </LinearLayout>
</com.android.setupwizardlib.GlifLayout>
</LinearLayout>

View File

@@ -15,6 +15,7 @@
--> -->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
@@ -24,14 +25,14 @@
<CheckBox <CheckBox
android:id="@+id/erase_esim" android:id="@+id/erase_esim"
style="@style/SuwCheckBox"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:paddingEnd="@dimen/reset_checkbox_padding_end"
android:focusable="false" android:focusable="false"
android:clickable="false" android:clickable="false"
android:checked="true" android:checked="true"
android:duplicateParentState="true" /> android:duplicateParentState="true"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -41,16 +42,14 @@
<TextView <TextView
android:id="@+id/erase_esim_title" android:id="@+id/erase_esim_title"
style="@style/TextAppearance.SuwGlifItemTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"/>
android:paddingTop="@dimen/reset_checkbox_title_padding_top"
android:textSize="@dimen/reset_checkbox_title_text_size" />
<TextView <TextView
style="@style/TextAppearance.SuwGlifItemSummary"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="@dimen/reset_checkbox_summary_padding_top" android:text="@string/reset_esim_desc"/>
android:textSize="@dimen/reset_checkbox_summary_text_size"
android:text="@string/reset_esim_desc" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@@ -301,7 +301,7 @@
<!-- Margin for the reset screens --> <!-- Margin for the reset screens -->
<dimen name="reset_network_margin_start">72dp</dimen> <dimen name="reset_network_margin_start">72dp</dimen>
<dimen name="reset_network_margin_end">12dp</dimen> <dimen name="reset_network_margin_end">12dp</dimen>
<dimen name="reset_master_clear_margin_start">72dp</dimen> <dimen name="reset_master_clear_margin_start">32dp</dimen>
<dimen name="reset_master_clear_margin_end">12dp</dimen> <dimen name="reset_master_clear_margin_end">12dp</dimen>
<!-- Padding for screen pinning --> <!-- Padding for screen pinning -->

View File

@@ -458,9 +458,4 @@
<item name="android:paddingBottom">24dp</item> <item name="android:paddingBottom">24dp</item>
</style> </style>
<style name="master_clear_item_label" parent="android:Widget.TextView">
<item name="android:textDirection">locale</item>
<item name="android:textSize">18sp</item>
</style>
</resources> </resources>

View File

@@ -21,7 +21,7 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription; import android.accounts.AuthenticatorDescription;
import android.annotation.Nullable; import android.app.ActionBar;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.ContentResolver; import android.content.ContentResolver;
@@ -31,6 +31,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
@@ -61,8 +62,9 @@ import com.android.settings.core.SubSettingLauncher;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmLockPattern; import com.android.settings.password.ConfirmLockPattern;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.setupwizardlib.TemplateLayout;
import com.android.setupwizardlib.template.ButtonFooterMixin;
import java.util.List; import java.util.List;
@@ -79,8 +81,10 @@ import java.util.List;
public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutListener { public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutListener {
private static final String TAG = "MasterClear"; private static final String TAG = "MasterClear";
@VisibleForTesting static final int KEYGUARD_REQUEST = 55; @VisibleForTesting
@VisibleForTesting static final int CREDENTIAL_CONFIRM_REQUEST = 56; static final int KEYGUARD_REQUEST = 55;
@VisibleForTesting
static final int CREDENTIAL_CONFIRM_REQUEST = 56;
private static final String KEY_SHOW_ESIM_RESET_CHECKBOX private static final String KEY_SHOW_ESIM_RESET_CHECKBOX
= "masterclear.allow_retain_esim_profiles_after_fdr"; = "masterclear.allow_retain_esim_profiles_after_fdr";
@@ -89,27 +93,41 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
static final String ERASE_ESIMS_EXTRA = "erase_esim"; static final String ERASE_ESIMS_EXTRA = "erase_esim";
private View mContentView; private View mContentView;
@VisibleForTesting Button mInitiateButton; @VisibleForTesting
Button mInitiateButton;
private View mExternalStorageContainer; private View mExternalStorageContainer;
@VisibleForTesting CheckBox mExternalStorage; @VisibleForTesting
CheckBox mExternalStorage;
private View mEsimStorageContainer; private View mEsimStorageContainer;
@VisibleForTesting CheckBox mEsimStorage; @VisibleForTesting
@VisibleForTesting ScrollView mScrollView; CheckBox mEsimStorage;
@VisibleForTesting
ScrollView mScrollView;
@Override @Override
public void onGlobalLayout() { public void onGlobalLayout() {
mInitiateButton.setEnabled(hasReachedBottom(mScrollView)); mInitiateButton.setEnabled(hasReachedBottom(mScrollView));
} }
@Override private void setUpActionBarAndTitle() {
public void onCreate(@Nullable Bundle savedInstanceState) { final Activity activity = getActivity();
super.onCreate(savedInstanceState); if (activity == null) {
getActivity().setTitle(R.string.master_clear_short_title); Log.e(TAG, "No activity attached, skipping setUpActionBarAndTitle");
return;
}
final ActionBar actionBar = activity.getActionBar();
if (actionBar == null) {
Log.e(TAG, "No actionbar, skipping setUpActionBarAndTitle");
return;
}
actionBar.hide();
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} }
/** /**
* Keyguard validation is run using the standard {@link ConfirmLockPattern} * Keyguard validation is run using the standard {@link ConfirmLockPattern}
* component as a subactivity * component as a subactivity
*
* @param request the request code to be returned once confirmation finishes * @param request the request code to be returned once confirmation finishes
* @return true if confirmation launched * @return true if confirmation launched
*/ */
@@ -189,8 +207,8 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
Account[] accounts = am.getAccountsByType(accountType); Account[] accounts = am.getAccountsByType(accountType);
if (accounts != null && accounts.length > 0) { if (accounts != null && accounts.length > 0) {
final Intent requestAccountConfirmation = new Intent() final Intent requestAccountConfirmation = new Intent()
.setPackage(packageName) .setPackage(packageName)
.setComponent(new ComponentName(packageName, className)); .setComponent(new ComponentName(packageName, className));
// Check to make sure that the intent is supported. // Check to make sure that the intent is supported.
final PackageManager pm = context.getPackageManager(); final PackageManager pm = context.getPackageManager();
final ResolveInfo resolution = pm.resolveActivity(requestAccountConfirmation, 0); final ResolveInfo resolution = pm.resolveActivity(requestAccountConfirmation, 0);
@@ -259,8 +277,9 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
*/ */
@VisibleForTesting @VisibleForTesting
void establishInitialState() { void establishInitialState() {
mInitiateButton = mContentView.findViewById(R.id.initiate_master_clear); setUpActionBarAndTitle();
mInitiateButton.setOnClickListener(mInitiateListener); setUpInitiateButton();
mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container); mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
mExternalStorage = mContentView.findViewById(R.id.erase_external); mExternalStorage = mContentView.findViewById(R.id.erase_external);
mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container); mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
@@ -334,7 +353,7 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
mScrollView.setOnScrollChangeListener(new OnScrollChangeListener() { mScrollView.setOnScrollChangeListener(new OnScrollChangeListener() {
@Override @Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX,
int oldScrollY) { int oldScrollY) {
if (v instanceof ScrollView && hasReachedBottom((ScrollView) v)) { if (v instanceof ScrollView && hasReachedBottom((ScrollView) v)) {
mInitiateButton.setEnabled(true); mInitiateButton.setEnabled(true);
mScrollView.setOnScrollChangeListener(null); mScrollView.setOnScrollChangeListener(null);
@@ -360,8 +379,8 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
} }
ContentResolver cr = context.getContentResolver(); ContentResolver cr = context.getContentResolver();
return Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) != 0 return Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) != 0
|| Settings.Global.getInt( || Settings.Global.getInt(
cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
} }
@VisibleForTesting @VisibleForTesting
@@ -388,21 +407,36 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
return diff <= 0; return diff <= 0;
} }
private void setUpInitiateButton() {
if (mInitiateButton != null) {
return;
}
final TemplateLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
buttonFooterMixin.removeAllViews();
buttonFooterMixin.addSpace();
buttonFooterMixin.addSpace();
mInitiateButton = buttonFooterMixin.addButton(R.string.master_clear_button_text,
R.style.SuwGlifButton_Primary);
mInitiateButton.setOnClickListener(mInitiateListener);
}
private void getContentDescription(View v, StringBuffer description) { private void getContentDescription(View v, StringBuffer description) {
if (v.getVisibility() != View.VISIBLE) { if (v.getVisibility() != View.VISIBLE) {
return; return;
} }
if (v instanceof ViewGroup) { if (v instanceof ViewGroup) {
ViewGroup vGroup = (ViewGroup) v; ViewGroup vGroup = (ViewGroup) v;
for (int i = 0; i < vGroup.getChildCount(); i++) { for (int i = 0; i < vGroup.getChildCount(); i++) {
View nextChild = vGroup.getChildAt(i); View nextChild = vGroup.getChildAt(i);
getContentDescription(nextChild, description); getContentDescription(nextChild, description);
} }
} else if (v instanceof TextView) { } else if (v instanceof TextView) {
TextView vText = (TextView) v; TextView vText = (TextView) v;
description.append(vText.getText()); description.append(vText.getText());
description.append(","); // Allow Talkback to pause between sections. description.append(","); // Allow Talkback to pause between sections.
} }
} }
private boolean isExtStorageEncrypted() { private boolean isExtStorageEncrypted() {
@@ -412,7 +446,7 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
private void loadAccountList(final UserManager um) { private void loadAccountList(final UserManager um) {
View accountsLabel = mContentView.findViewById(R.id.accounts_label); View accountsLabel = mContentView.findViewById(R.id.accounts_label);
LinearLayout contents = (LinearLayout)mContentView.findViewById(R.id.accounts); LinearLayout contents = (LinearLayout) mContentView.findViewById(R.id.accounts);
contents.removeAllViews(); contents.removeAllViews();
Context context = getActivity(); Context context = getActivity();
@@ -421,7 +455,7 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
AccountManager mgr = AccountManager.get(context); AccountManager mgr = AccountManager.get(context);
LayoutInflater inflater = (LayoutInflater)context.getSystemService( LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE); Context.LAYOUT_INFLATER_SERVICE);
int accountsCount = 0; int accountsCount = 0;

View File

@@ -16,18 +16,23 @@
package com.android.settings; package com.android.settings;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.service.oemlock.OemLockManager; import android.service.oemlock.OemLockManager;
import android.service.persistentdata.PersistentDataBlockManager; import android.service.persistentdata.PersistentDataBlockManager;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -37,8 +42,9 @@ import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.InstrumentedFragment;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.setupwizardlib.TemplateLayout;
import com.android.setupwizardlib.template.ButtonFooterMixin;
/** /**
* Confirm and execute a reset of the device to a clean "just out of the box" * Confirm and execute a reset of the device to a clean "just out of the box"
@@ -51,6 +57,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal;
* This is the confirmation screen. * This is the confirmation screen.
*/ */
public class MasterClearConfirm extends InstrumentedFragment { public class MasterClearConfirm extends InstrumentedFragment {
private final static String TAG = "MasterClearConfirm";
private View mContentView; private View mContentView;
private boolean mEraseSdCard; private boolean mEraseSdCard;
@@ -103,9 +110,11 @@ public class MasterClearConfirm extends InstrumentedFragment {
mProgressDialog.show(); mProgressDialog.show();
// need to prevent orientation changes as we're about to go into // need to prevent orientation changes as we're about to go into
// a long IO request, so we won't be able to access inflate resources on flash // a long IO request, so we won't be able to access inflate resources on
// flash
mOldOrientation = getActivity().getRequestedOrientation(); mOldOrientation = getActivity().getRequestedOrientation();
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LOCKED);
} }
}.execute(); }.execute();
} else { } else {
@@ -140,8 +149,29 @@ public class MasterClearConfirm extends InstrumentedFragment {
* Configure the UI for the final confirmation interaction * Configure the UI for the final confirmation interaction
*/ */
private void establishFinalConfirmationState() { private void establishFinalConfirmationState() {
mContentView.findViewById(R.id.execute_master_clear) final TemplateLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
.setOnClickListener(mFinalClickListener);
final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
buttonFooterMixin.removeAllViews();
buttonFooterMixin.addSpace();
buttonFooterMixin.addSpace();
buttonFooterMixin.addButton(R.string.master_clear_button_text,
R.style.SuwGlifButton_Primary).setOnClickListener(mFinalClickListener);
}
private void setUpActionBarAndTitle() {
final Activity activity = getActivity();
if (activity == null) {
Log.e(TAG, "No activity attached, skipping setUpActionBarAndTitle");
return;
}
final ActionBar actionBar = activity.getActionBar();
if (actionBar == null) {
Log.e(TAG, "No actionbar, skipping setUpActionBarAndTitle");
return;
}
actionBar.hide();
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} }
@Override @Override
@@ -160,6 +190,7 @@ public class MasterClearConfirm extends InstrumentedFragment {
return new View(getActivity()); return new View(getActivity());
} }
mContentView = inflater.inflate(R.layout.master_clear_confirm, null); mContentView = inflater.inflate(R.layout.master_clear_confirm, null);
setUpActionBarAndTitle();
establishFinalConfirmationState(); establishFinalConfirmationState();
setAccessibilityTitle(); setAccessibilityTitle();
return mContentView; return mContentView;
@@ -167,8 +198,7 @@ public class MasterClearConfirm extends InstrumentedFragment {
private void setAccessibilityTitle() { private void setAccessibilityTitle() {
CharSequence currentTitle = getActivity().getTitle(); CharSequence currentTitle = getActivity().getTitle();
TextView confirmationMessage = TextView confirmationMessage = mContentView.findViewById(R.id.master_clear_confirm);
(TextView) mContentView.findViewById(R.id.master_clear_confirm);
if (confirmationMessage != null) { if (confirmationMessage != null) {
String accessibleText = new StringBuilder(currentTitle).append(",").append( String accessibleText = new StringBuilder(currentTitle).append(",").append(
confirmationMessage.getText()).toString(); confirmationMessage.getText()).toString();

View File

@@ -122,8 +122,8 @@ public class MasterClearTest {
verify(context).startActivity(intent.capture()); verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS) assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false)) .getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false))
.isTrue(); .isTrue();
} }
@Test @Test
@@ -139,8 +139,8 @@ public class MasterClearTest {
verify(context).startActivity(intent.capture()); verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS) assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false)) .getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false))
.isFalse(); .isFalse();
} }
@Test @Test
@@ -210,11 +210,10 @@ public class MasterClearTest {
ShadowUtils.setIsDemoUser(true); ShadowUtils.setIsDemoUser(true);
final ComponentName componentName = final ComponentName componentName =
ComponentName.unflattenFromString("com.android.retaildemo/.DeviceAdminReceiver"); ComponentName.unflattenFromString("com.android.retaildemo/.DeviceAdminReceiver");
ShadowUtils.setDeviceOwnerComponent(componentName); ShadowUtils.setDeviceOwnerComponent(componentName);
mMasterClear.mInitiateListener mMasterClear.mInitiateListener.onClick(mContentView);
.onClick(mContentView.findViewById(R.id.initiate_master_clear));
final Intent intent = mShadowActivity.getNextStartedActivity(); final Intent intent = mShadowActivity.getNextStartedActivity();
assertThat(Intent.ACTION_FACTORY_RESET).isEqualTo(intent.getAction()); assertThat(Intent.ACTION_FACTORY_RESET).isEqualTo(intent.getAction());
assertThat(componentName).isNotNull(); assertThat(componentName).isNotNull();
@@ -240,7 +239,8 @@ public class MasterClearTest {
doNothing().when(mMasterClear).establishInitialState(); doNothing().when(mMasterClear).establishInitialState();
mMasterClear mMasterClear
.onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_CANCELED, null); .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_CANCELED,
null);
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST)); verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
verify(mMasterClear, times(1)).establishInitialState(); verify(mMasterClear, times(1)).establishInitialState();
@@ -255,7 +255,7 @@ public class MasterClearTest {
doNothing().when(mMasterClear).showAccountCredentialConfirmation(eq(mMockIntent)); doNothing().when(mMasterClear).showAccountCredentialConfirmation(eq(mMockIntent));
mMasterClear mMasterClear
.onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null); .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST)); verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
verify(mMasterClear, times(0)).establishInitialState(); verify(mMasterClear, times(0)).establishInitialState();
@@ -270,7 +270,7 @@ public class MasterClearTest {
doNothing().when(mMasterClear).showFinalConfirmation(); doNothing().when(mMasterClear).showFinalConfirmation();
mMasterClear mMasterClear
.onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null); .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST)); verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
verify(mMasterClear, times(0)).establishInitialState(); verify(mMasterClear, times(0)).establishInitialState();
@@ -281,14 +281,14 @@ public class MasterClearTest {
@Test @Test
public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() { public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() {
doReturn(true).when(mMasterClear) doReturn(true).when(mMasterClear)
.isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST)); .isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
doNothing().when(mMasterClear).showFinalConfirmation(); doNothing().when(mMasterClear).showFinalConfirmation();
mMasterClear.onActivityResultInternal( mMasterClear.onActivityResultInternal(
MasterClear.CREDENTIAL_CONFIRM_REQUEST, Activity.RESULT_OK, null); MasterClear.CREDENTIAL_CONFIRM_REQUEST, Activity.RESULT_OK, null);
verify(mMasterClear, times(1)) verify(mMasterClear, times(1))
.isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST)); .isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
verify(mMasterClear, times(0)).establishInitialState(); verify(mMasterClear, times(0)).establishInitialState();
verify(mMasterClear, times(0)).getAccountConfirmationIntent(); verify(mMasterClear, times(0)).getAccountConfirmationIntent();
verify(mMasterClear, times(1)).showFinalConfirmation(); verify(mMasterClear, times(1)).showFinalConfirmation();
@@ -306,9 +306,9 @@ public class MasterClearTest {
when(mMasterClear.getActivity()).thenReturn(mMockActivity); when(mMasterClear.getActivity()).thenReturn(mMockActivity);
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE); when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package)) when(mMockActivity.getString(R.string.account_confirmation_package))
.thenReturn(TEST_CONFIRMATION_PACKAGE); .thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class)) when(mMockActivity.getString(R.string.account_confirmation_class))
.thenReturn(TEST_CONFIRMATION_CLASS); .thenReturn(TEST_CONFIRMATION_CLASS);
Account[] accounts = new Account[0]; Account[] accounts = new Account[0];
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager); when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
@@ -321,10 +321,10 @@ public class MasterClearTest {
when(mMasterClear.getActivity()).thenReturn(mMockActivity); when(mMasterClear.getActivity()).thenReturn(mMockActivity);
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE); when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package)) when(mMockActivity.getString(R.string.account_confirmation_package))
.thenReturn(TEST_CONFIRMATION_PACKAGE); .thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class)) when(mMockActivity.getString(R.string.account_confirmation_class))
.thenReturn(TEST_CONFIRMATION_CLASS); .thenReturn(TEST_CONFIRMATION_CLASS);
Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) }; Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager); when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts); when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
// The package manager should not resolve the confirmation intent targeting the non-existent // The package manager should not resolve the confirmation intent targeting the non-existent
@@ -339,11 +339,11 @@ public class MasterClearTest {
// Only try to show account confirmation if the appropriate resource overlays are available. // Only try to show account confirmation if the appropriate resource overlays are available.
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE); when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package)) when(mMockActivity.getString(R.string.account_confirmation_package))
.thenReturn(TEST_CONFIRMATION_PACKAGE); .thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class)) when(mMockActivity.getString(R.string.account_confirmation_class))
.thenReturn(TEST_CONFIRMATION_CLASS); .thenReturn(TEST_CONFIRMATION_CLASS);
// Add accounts to trigger the search for a resolving intent. // Add accounts to trigger the search for a resolving intent.
Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) }; Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager); when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts); when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
// The package manager should not resolve the confirmation intent targeting the non-existent // The package manager should not resolve the confirmation intent targeting the non-existent
@@ -366,17 +366,19 @@ public class MasterClearTest {
public void testShowAccountCredentialConfirmation() { public void testShowAccountCredentialConfirmation() {
// Finally mock out the startActivityForResultCall // Finally mock out the startActivityForResultCall
doNothing().when(mMasterClear) doNothing().when(mMasterClear)
.startActivityForResult(eq(mMockIntent), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST)); .startActivityForResult(eq(mMockIntent),
eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
mMasterClear.showAccountCredentialConfirmation(mMockIntent); mMasterClear.showAccountCredentialConfirmation(mMockIntent);
verify(mMasterClear, times(1)) verify(mMasterClear, times(1))
.startActivityForResult(eq(mMockIntent), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST)); .startActivityForResult(eq(mMockIntent),
eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
} }
@Test @Test
public void testIsValidRequestCode() { public void testIsValidRequestCode() {
assertThat(mMasterClear.isValidRequestCode(MasterClear.KEYGUARD_REQUEST)).isTrue(); assertThat(mMasterClear.isValidRequestCode(MasterClear.KEYGUARD_REQUEST)).isTrue();
assertThat(mMasterClear.isValidRequestCode(MasterClear.CREDENTIAL_CONFIRM_REQUEST)) assertThat(mMasterClear.isValidRequestCode(MasterClear.CREDENTIAL_CONFIRM_REQUEST))
.isTrue(); .isTrue();
assertThat(mMasterClear.isValidRequestCode(0)).isFalse(); assertThat(mMasterClear.isValidRequestCode(0)).isFalse();
} }