diff --git a/aconfig/settings_flag_declarations.aconfig b/aconfig/settings_flag_declarations.aconfig new file mode 100644 index 00000000000..c4c33b09930 --- /dev/null +++ b/aconfig/settings_flag_declarations.aconfig @@ -0,0 +1,8 @@ +package: "com.android.settings.flags" + +flag { + name: "show_factory_reset_cancel_button" + namespace: "android_settings" + description: "This flag controls whether to show a Cancel button when factory reset" + bug: "300634367" +} diff --git a/src/com/android/settings/MainClear.java b/src/com/android/settings/MainClear.java index 58fc0d5f942..0aba5ca4614 100644 --- a/src/com/android/settings/MainClear.java +++ b/src/com/android/settings/MainClear.java @@ -63,6 +63,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.core.InstrumentedFragment; import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; +import com.android.settings.flags.Flags; import com.android.settings.network.SubscriptionUtil; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ConfirmLockPattern; @@ -431,14 +432,24 @@ public class MainClear extends InstrumentedFragment implements OnGlobalLayoutLis final GlifLayout layout = mContentView.findViewById(R.id.setup_wizard_layout); final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class); + final Activity activity = getActivity(); mixin.setPrimaryButton( - new FooterButton.Builder(getActivity()) + new FooterButton.Builder(activity) .setText(R.string.main_clear_button_text) .setListener(mInitiateListener) .setButtonType(ButtonType.OTHER) .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary) - .build() - ); + .build()); + if (Flags.showFactoryResetCancelButton()) { + mixin.setSecondaryButton( + new FooterButton.Builder(activity) + .setText(android.R.string.cancel) + .setListener(view -> activity.onBackPressed()) + .setButtonType(ButtonType.CANCEL) + .setTheme( + com.google.android.setupdesign.R.style.SudGlifButton_Secondary) + .build()); + } mInitiateButton = mixin.getPrimaryButton(); } diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp index 0f045a8ca38..327b6aad1c4 100644 --- a/tests/unit/Android.bp +++ b/tests/unit/Android.bp @@ -21,6 +21,7 @@ android_test { "aconfig_settings_flags_lib", "androidx.arch.core_core-testing", "androidx.test.core", + "androidx.test.espresso.core", "androidx.test.rules", "androidx.test.ext.junit", "androidx.preference_preference", diff --git a/tests/unit/src/com/android/settings/MainClearTest.kt b/tests/unit/src/com/android/settings/MainClearTest.kt new file mode 100644 index 00000000000..05f06dfd4d6 --- /dev/null +++ b/tests/unit/src/com/android/settings/MainClearTest.kt @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023 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 android.platform.test.flag.junit.SetFlagsRule +import androidx.test.core.app.ActivityScenario +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions.doesNotExist +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settings.Settings.FactoryResetActivity +import com.android.settings.flags.Flags +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** Test [MainClear]. */ +@RunWith(AndroidJUnit4::class) +class MainClearTest { + @get:Rule + val mSetFlagsRule = SetFlagsRule() + + @Test + fun factoryResetCancelButton_flagDisabled_noCancelButton() { + mSetFlagsRule.disableFlags(Flags.FLAG_SHOW_FACTORY_RESET_CANCEL_BUTTON) + ActivityScenario.launch(FactoryResetActivity::class.java).use { + ensurePrimaryButton() + onView(withText(android.R.string.cancel)).check(doesNotExist()) + it.onActivity { activity -> assertThat(activity.isFinishing).isFalse() } + } + } + + @Test + fun factoryResetCancelButton_flagEnabled_showCancelButton() { + mSetFlagsRule.enableFlags(Flags.FLAG_SHOW_FACTORY_RESET_CANCEL_BUTTON) + ActivityScenario.launch(FactoryResetActivity::class.java).use { + ensurePrimaryButton() + it.onActivity { activity -> assertThat(activity.isFinishing).isFalse() } + + // Note: onView CANNOT be called within onActivity block, which runs in the main thread + onView(withText(android.R.string.cancel)).check(matches(isDisplayed())).perform(click()) + + it.onActivity { activity -> assertThat(activity.isFinishing).isTrue() } + } + } + + private fun ensurePrimaryButton() { + onView(withText(R.string.main_clear_button_text)).check(matches(isDisplayed())) + } +} \ No newline at end of file