Loading src/com/android/settings/localepicker/LocaleDialogFragment.java +39 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.localepicker; import static android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT; import android.app.Activity; import android.app.Dialog; import android.app.settings.SettingsEnums; Loading @@ -23,15 +25,17 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentManager; import com.android.internal.app.LocaleStore; import com.android.settings.R; Loading @@ -53,6 +57,12 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { static final String ARG_SHOW_DIALOG = "arg_show_dialog"; private boolean mShouldKeepDialog; private AlertDialog mAlertDialog; private OnBackInvokedDispatcher mBackDispatcher; private OnBackInvokedCallback mBackCallback = () -> { Log.d(TAG, "Do not back to previous page if the dialog is displaying."); }; public static LocaleDialogFragment newInstance() { return new LocaleDialogFragment(); Loading Loading @@ -108,9 +118,15 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { if (!dialogContent.mNegativeButton.isEmpty()) { builder.setNegativeButton(dialogContent.mNegativeButton, controller); } AlertDialog alertDialog = builder.create(); alertDialog.setCanceledOnTouchOutside(false); return alertDialog; mAlertDialog = builder.create(); getOnBackInvokedDispatcher().registerOnBackInvokedCallback(PRIORITY_DEFAULT, mBackCallback); mAlertDialog.setCanceledOnTouchOutside(false); mAlertDialog.setOnDismissListener(dialogInterface -> { mAlertDialog.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback( mBackCallback); }); return mAlertDialog; } private static void setDialogTitle(View root, String content) { Loading @@ -129,6 +145,25 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { textView.setText(content); } @VisibleForTesting public OnBackInvokedCallback getBackInvokedCallback() { return mBackCallback; } @VisibleForTesting public void setBackDispatcher(OnBackInvokedDispatcher dispatcher) { mBackDispatcher = dispatcher; } @VisibleForTesting public OnBackInvokedDispatcher getOnBackInvokedDispatcher() { if (mBackDispatcher != null) { return mBackDispatcher; } else { return mAlertDialog.getOnBackInvokedDispatcher(); } } @VisibleForTesting LocaleDialogController getLocaleDialogController(Context context, LocaleDialogFragment dialogFragment, LocaleListEditor parentFragment) { Loading @@ -155,11 +190,6 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { mParent = parentFragment; } LocaleDialogController(@NonNull LocaleDialogFragment dialogFragment, LocaleListEditor parent) { this(dialogFragment.getContext(), dialogFragment, parent); } @Override public void onClick(DialogInterface dialog, int which) { if (mDialogType == DIALOG_CONFIRM_SYSTEM_DEFAULT) { Loading tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * 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.localepicker; import static com.android.settings.localepicker.LocaleDialogFragment.ARG_DIALOG_TYPE; import static com.android.settings.localepicker.LocaleDialogFragment.ARG_TARGET_LOCALE; import static com.android.settings.localepicker.LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import android.os.Bundle; import android.window.OnBackInvokedDispatcher; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import com.android.internal.app.LocaleStore; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.utils.ActivityControllerWrapper; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.util.Locale; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowAlertDialogCompat.class}) public class LocaleDialogFragmentTest { @Mock private OnBackInvokedDispatcher mOnBackInvokedDispatcher; private FragmentActivity mActivity; private LocaleDialogFragment mDialogFragment; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mActivity = (FragmentActivity) ActivityControllerWrapper.setup( Robolectric.buildActivity(FragmentActivity.class)).get(); mDialogFragment = LocaleDialogFragment.newInstance(); LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(Locale.ENGLISH); Bundle args = new Bundle(); args.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT); args.putSerializable(ARG_TARGET_LOCALE, localeInfo); mDialogFragment.setArguments(args); FragmentManager fragmentManager = mActivity.getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(mDialogFragment, null); fragmentTransaction.commit(); } @Test public void onCreateDialog_onBackInvokedCallbackIsRegistered() { mDialogFragment.setBackDispatcher(mOnBackInvokedDispatcher); mDialogFragment.onCreateDialog(null); verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any()); } @Test public void onBackInvoked_dialogIsStillDisplaying() { mDialogFragment.setBackDispatcher(mOnBackInvokedDispatcher); AlertDialog alertDialog = (AlertDialog) mDialogFragment.onCreateDialog(null); alertDialog.show(); assertThat(alertDialog).isNotNull(); assertThat(alertDialog.isShowing()).isTrue(); mOnBackInvokedDispatcher.registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any()); mDialogFragment.getBackInvokedCallback().onBackInvoked(); assertThat(alertDialog.isShowing()).isTrue(); } } Loading
src/com/android/settings/localepicker/LocaleDialogFragment.java +39 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.localepicker; import static android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT; import android.app.Activity; import android.app.Dialog; import android.app.settings.SettingsEnums; Loading @@ -23,15 +25,17 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentManager; import com.android.internal.app.LocaleStore; import com.android.settings.R; Loading @@ -53,6 +57,12 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { static final String ARG_SHOW_DIALOG = "arg_show_dialog"; private boolean mShouldKeepDialog; private AlertDialog mAlertDialog; private OnBackInvokedDispatcher mBackDispatcher; private OnBackInvokedCallback mBackCallback = () -> { Log.d(TAG, "Do not back to previous page if the dialog is displaying."); }; public static LocaleDialogFragment newInstance() { return new LocaleDialogFragment(); Loading Loading @@ -108,9 +118,15 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { if (!dialogContent.mNegativeButton.isEmpty()) { builder.setNegativeButton(dialogContent.mNegativeButton, controller); } AlertDialog alertDialog = builder.create(); alertDialog.setCanceledOnTouchOutside(false); return alertDialog; mAlertDialog = builder.create(); getOnBackInvokedDispatcher().registerOnBackInvokedCallback(PRIORITY_DEFAULT, mBackCallback); mAlertDialog.setCanceledOnTouchOutside(false); mAlertDialog.setOnDismissListener(dialogInterface -> { mAlertDialog.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback( mBackCallback); }); return mAlertDialog; } private static void setDialogTitle(View root, String content) { Loading @@ -129,6 +145,25 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { textView.setText(content); } @VisibleForTesting public OnBackInvokedCallback getBackInvokedCallback() { return mBackCallback; } @VisibleForTesting public void setBackDispatcher(OnBackInvokedDispatcher dispatcher) { mBackDispatcher = dispatcher; } @VisibleForTesting public OnBackInvokedDispatcher getOnBackInvokedDispatcher() { if (mBackDispatcher != null) { return mBackDispatcher; } else { return mAlertDialog.getOnBackInvokedDispatcher(); } } @VisibleForTesting LocaleDialogController getLocaleDialogController(Context context, LocaleDialogFragment dialogFragment, LocaleListEditor parentFragment) { Loading @@ -155,11 +190,6 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { mParent = parentFragment; } LocaleDialogController(@NonNull LocaleDialogFragment dialogFragment, LocaleListEditor parent) { this(dialogFragment.getContext(), dialogFragment, parent); } @Override public void onClick(DialogInterface dialog, int which) { if (mDialogType == DIALOG_CONFIRM_SYSTEM_DEFAULT) { Loading
tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * 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.localepicker; import static com.android.settings.localepicker.LocaleDialogFragment.ARG_DIALOG_TYPE; import static com.android.settings.localepicker.LocaleDialogFragment.ARG_TARGET_LOCALE; import static com.android.settings.localepicker.LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import android.os.Bundle; import android.window.OnBackInvokedDispatcher; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import com.android.internal.app.LocaleStore; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.utils.ActivityControllerWrapper; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.util.Locale; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowAlertDialogCompat.class}) public class LocaleDialogFragmentTest { @Mock private OnBackInvokedDispatcher mOnBackInvokedDispatcher; private FragmentActivity mActivity; private LocaleDialogFragment mDialogFragment; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mActivity = (FragmentActivity) ActivityControllerWrapper.setup( Robolectric.buildActivity(FragmentActivity.class)).get(); mDialogFragment = LocaleDialogFragment.newInstance(); LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(Locale.ENGLISH); Bundle args = new Bundle(); args.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT); args.putSerializable(ARG_TARGET_LOCALE, localeInfo); mDialogFragment.setArguments(args); FragmentManager fragmentManager = mActivity.getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(mDialogFragment, null); fragmentTransaction.commit(); } @Test public void onCreateDialog_onBackInvokedCallbackIsRegistered() { mDialogFragment.setBackDispatcher(mOnBackInvokedDispatcher); mDialogFragment.onCreateDialog(null); verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any()); } @Test public void onBackInvoked_dialogIsStillDisplaying() { mDialogFragment.setBackDispatcher(mOnBackInvokedDispatcher); AlertDialog alertDialog = (AlertDialog) mDialogFragment.onCreateDialog(null); alertDialog.show(); assertThat(alertDialog).isNotNull(); assertThat(alertDialog.isShowing()).isTrue(); mOnBackInvokedDispatcher.registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any()); mDialogFragment.getBackInvokedCallback().onBackInvoked(); assertThat(alertDialog.isShowing()).isTrue(); } }