diff --git a/res/layout/locale_drag_cell.xml b/res/layout/locale_drag_cell.xml index 7b932f39a02..47bf70a473e 100644 --- a/res/layout/locale_drag_cell.xml +++ b/res/layout/locale_drag_cell.xml @@ -56,6 +56,17 @@ android:layout_toStartOf="@+id/dragHandle" android:layout_below="@id/label"/> + + Languages + + Preferred language order + + + System language + Remove @@ -502,13 +508,13 @@ Preferred Language - App Languages + App languages Set the language for each app - App Language + App language Suggested languages @@ -531,6 +537,18 @@ Only apps that support language selection are shown here. + + Your system, apps, and websites use the first supported language from your preferred languages. + + + To select a language for each app, go to app language settings. + + + Learn more about languages + + + https://support.google.com/android?p=per_language_app_settings + Remove selected language? @@ -546,7 +564,7 @@ Keep at least one preferred language - May not be available in some apps + Not available as system language Move up diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml index 4e58e66887d..96a3f85a46a 100644 --- a/res/xml/configure_notification_settings.xml +++ b/res/xml/configure_notification_settings.xml @@ -156,7 +156,7 @@ android:title="@string/notification_pulse_title" settings:controller="com.android.settings.notification.PulseNotificationPreferenceController"/> - + + + + + + + + + + + + + diff --git a/src/com/android/settings/applications/AppLocaleUtil.java b/src/com/android/settings/applications/AppLocaleUtil.java index 8c3671ed943..79406f05224 100644 --- a/src/com/android/settings/applications/AppLocaleUtil.java +++ b/src/com/android/settings/applications/AppLocaleUtil.java @@ -100,8 +100,8 @@ public class AppLocaleUtil { */ public static boolean isAppLocaleSupported(Context context, String packageName) { LocaleList localeList = getPackageLocales(context, packageName); - if (localeList != null && localeList.size() > 0) { - return true; + if (localeList != null) { + return localeList.size() > 0; } if (FeatureFlagUtils.isEnabled( diff --git a/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java b/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java index f406d8763ff..6bf94a61200 100644 --- a/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java @@ -22,7 +22,6 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.text.TextUtils; -import android.util.FeatureFlagUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; @@ -51,9 +50,7 @@ public class AppLocalePreferenceController extends AppInfoPreferenceControllerBa @Override public int getAvailabilityStatus() { - boolean isFeatureOn = FeatureFlagUtils - .isEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION); - return isFeatureOn && canDisplayLocaleUi() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; + return canDisplayLocaleUi() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } @Override diff --git a/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceController.java b/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceController.java deleted file mode 100644 index aa12b626eb7..00000000000 --- a/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceController.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2021 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.applications.appinfo; - -import android.content.Context; -import android.util.FeatureFlagUtils; - -import com.android.settings.core.BasePreferenceController; - -/** - * A controller to update current locale information of application - * and a entry to launch {@link ManageApplications}. - * TODO(209775925) After feature release, this class may be removed. - */ -public class ManageAppLocalePreferenceController extends BasePreferenceController { - public ManageAppLocalePreferenceController(Context context, String key) { - super(context, key); - } - - @Override - public int getAvailabilityStatus() { - return FeatureFlagUtils - .isEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION) - ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; - } -} diff --git a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java index 7256511d2e6..1ae5daee348 100644 --- a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java +++ b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java @@ -77,7 +77,7 @@ public class SetupFingerprintEnrollFindSensor extends FingerprintEnrollFindSenso @NonNull public AlertDialog.Builder onCreateDialogBuilder() { - return new AlertDialog.Builder(getContext()) + return new AlertDialog.Builder(getActivity(), R.style.GlifV2ThemeAlertDialog) .setTitle(R.string.setup_fingerprint_enroll_skip_title) .setPositiveButton(R.string.skip_anyway_button_label, this) .setNegativeButton(R.string.go_back_button_label, this) diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java index ab9110d01ab..b3c2e3071af 100644 --- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java +++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java @@ -43,7 +43,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; - class LocaleDragAndDropAdapter extends RecyclerView.Adapter { @@ -154,8 +153,10 @@ class LocaleDragAndDropAdapter final LocaleDragCell dragCell = holder.getLocaleDragCell(); final String label = feedItem.getFullNameNative(); final String description = feedItem.getFullNameInUiLanguage(); + dragCell.setLabelAndDescription(label, description); dragCell.setLocalized(feedItem.isTranslated()); + dragCell.setCurrentDefault(feedItem.getLocale().equals(Locale.getDefault())); dragCell.setMiniLabel(mNumberFormatter.format(i + 1)); dragCell.setShowCheckbox(mRemoveMode); dragCell.setShowMiniLabel(!mRemoveMode); diff --git a/src/com/android/settings/localepicker/LocaleDragCell.java b/src/com/android/settings/localepicker/LocaleDragCell.java index ea86189b018..2f4cfefefb1 100644 --- a/src/com/android/settings/localepicker/LocaleDragCell.java +++ b/src/com/android/settings/localepicker/LocaleDragCell.java @@ -33,6 +33,7 @@ class LocaleDragCell extends RelativeLayout { private CheckBox mCheckbox; private TextView mMiniLabel; private TextView mLocalized; + private TextView mCurrentDefault; private ImageView mDragHandle; public LocaleDragCell(Context context, AttributeSet attrs) { @@ -44,6 +45,7 @@ class LocaleDragCell extends RelativeLayout { super.onFinishInflate(); mLabel = (TextView) findViewById(R.id.label); mLocalized = (TextView) findViewById(R.id.l10nWarn); + mCurrentDefault = (TextView) findViewById(R.id.default_locale); mMiniLabel = (TextView) findViewById(R.id.miniLabel); mCheckbox = (CheckBox) findViewById(R.id.checkbox); mDragHandle = (ImageView) findViewById(R.id.dragHandle); @@ -100,6 +102,14 @@ class LocaleDragCell extends RelativeLayout { invalidate(); } + /** + * Indicate current locale is system default. + */ + public void setCurrentDefault(boolean isCurrentDefault) { + mCurrentDefault.setVisibility(isCurrentDefault ? VISIBLE : GONE); + invalidate(); + } + public ImageView getDragHandle() { return mDragHandle; } diff --git a/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java b/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java new file mode 100644 index 00000000000..05c740139cc --- /dev/null +++ b/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2022 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 android.content.Context; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settingslib.HelpUtils; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.widget.FooterPreference; + +/** + * A controller to update current locale information of application. + */ +public class LocaleHelperPreferenceController extends AbstractPreferenceController { + private static final String TAG = LocaleHelperPreferenceController.class.getSimpleName(); + + private static final String KEY_FOOTER_LANGUAGE_PICKER = "footer_languages_picker"; + + public LocaleHelperPreferenceController(Context context) { + super(context); + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return KEY_FOOTER_LANGUAGE_PICKER; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + FooterPreference footerPreference = screen.findPreference(getPreferenceKey()); + updateFooterPreference(footerPreference); + } + + @VisibleForTesting + void updateFooterPreference(FooterPreference footerPreference) { + if (footerPreference != null) { + footerPreference.setLearnMoreAction(v -> openLocaleLearnMoreLink()); + footerPreference.setLearnMoreText(mContext.getString( + R.string.desc_locale_helper_footer_general)); + } + } + + private void openLocaleLearnMoreLink() { + mContext.startActivity( + HelpUtils.getHelpIntent( + mContext, + mContext.getString(R.string.link_locale_picker_footer_learn_more), + /*backupContext=*/"")); + } +} diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java index eac2dd1df3c..9db3468c9e1 100644 --- a/src/com/android/settings/localepicker/LocaleListEditor.java +++ b/src/com/android/settings/localepicker/LocaleListEditor.java @@ -36,6 +36,7 @@ import android.widget.TextView; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; +import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.RecyclerView; import com.android.internal.app.LocalePicker; @@ -46,6 +47,7 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexableRaw; +import com.android.settingslib.widget.LayoutPreference; import java.util.ArrayList; import java.util.List; @@ -64,6 +66,7 @@ public class LocaleListEditor extends RestrictedSettingsFragment { private static final int REQUEST_LOCALE_PICKER = 0; private static final String INDEX_KEY_ADD_LANGUAGE = "add_language"; + private static final String KEY_LANGUAGES_PICKER = "languages_picker"; private LocaleDragAndDropAdapter mAdapter; private Menu mMenu; @@ -72,6 +75,9 @@ public class LocaleListEditor extends RestrictedSettingsFragment { private boolean mShowingRemoveDialog; private boolean mIsUiRestricted; + private LayoutPreference mLocalePickerPreference; + private LocaleHelperPreferenceController mLocaleHelperPreferenceController; + public LocaleListEditor() { super(DISALLOW_CONFIG_LOCALE); } @@ -86,6 +92,14 @@ public class LocaleListEditor extends RestrictedSettingsFragment { super.onCreate(savedInstanceState); setHasOptionsMenu(true); + addPreferencesFromResource(R.xml.languages); + final Activity activity = getActivity(); + activity.setTitle(R.string.language_picker_title); + mLocaleHelperPreferenceController = new LocaleHelperPreferenceController(activity); + final PreferenceScreen screen = getPreferenceScreen(); + mLocalePickerPreference = screen.findPreference(KEY_LANGUAGES_PICKER); + mLocaleHelperPreferenceController.displayPreference(screen); + LocaleStore.fillCache(this.getContext()); final List feedsList = getUserLocaleList(); mAdapter = new LocaleDragAndDropAdapter(this.getContext(), feedsList); @@ -93,11 +107,8 @@ public class LocaleListEditor extends RestrictedSettingsFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstState) { - final View result = super.onCreateView(inflater, container, savedInstState); - final View myLayout = inflater.inflate(R.layout.locale_order_list, (ViewGroup) result); - - configureDragAndDrop(myLayout); - return result; + configureDragAndDrop(mLocalePickerPreference); + return super.onCreateView(inflater, container, savedInstState); } @Override @@ -287,8 +298,8 @@ public class LocaleListEditor extends RestrictedSettingsFragment { return result; } - private void configureDragAndDrop(View view) { - final RecyclerView list = view.findViewById(R.id.dragList); + private void configureDragAndDrop(LayoutPreference layout) { + final RecyclerView list = layout.findViewById(R.id.dragList); final LocaleLinearLayoutManager llm = new LocaleLinearLayoutManager(getContext(), mAdapter); llm.setAutoMeasureEnabled(true); list.setLayoutManager(llm); @@ -297,7 +308,7 @@ public class LocaleListEditor extends RestrictedSettingsFragment { mAdapter.setRecyclerView(list); list.setAdapter(mAdapter); - mAddLanguage = view.findViewById(R.id.add_language); + mAddLanguage = layout.findViewById(R.id.add_language); mAddLanguage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java index a6179e5306f..2c02db9c327 100644 --- a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java +++ b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java @@ -18,35 +18,49 @@ package com.android.settings.notification; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.service.notification.NotificationAssistantService; import androidx.fragment.app.Fragment; +import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.PrimarySwitchPreference; import com.google.common.annotations.VisibleForTesting; +import java.util.List; + public class NotificationAssistantPreferenceController extends TogglePreferenceController { private static final String TAG = "NASPreferenceController"; - private static final String KEY_NAS = "notification_assistant"; + static final String KEY_NAS = "notification_assistant"; private static final int AVAILABLE = 1; private final UserManager mUserManager; + private final PackageManager mPackageManager; private Fragment mFragment; private int mUserId = UserHandle.myUserId(); @VisibleForTesting protected NotificationBackend mNotificationBackend; + private ComponentName mDefaultNASComponent; + private Intent mNASSettingIntent; public NotificationAssistantPreferenceController(Context context) { super(context, KEY_NAS); mUserManager = UserManager.get(context); mNotificationBackend = new NotificationBackend(); + mPackageManager = context.getPackageManager(); + getDefaultNASIntent(); } + @Override public int getAvailabilityStatus() { return AVAILABLE; @@ -55,14 +69,13 @@ public class NotificationAssistantPreferenceController extends TogglePreferenceC @Override public boolean isChecked() { ComponentName acn = mNotificationBackend.getAllowedNotificationAssistant(); - ComponentName dcn = mNotificationBackend.getDefaultNotificationAssistant(); - return (acn != null && acn.equals(dcn)); + return (acn != null && acn.equals(mDefaultNASComponent)); } @Override public boolean setChecked(boolean isChecked) { ComponentName cn = isChecked - ? mNotificationBackend.getDefaultNotificationAssistant() : null; + ? mDefaultNASComponent : null; if (isChecked) { if (mFragment == null) { throw new IllegalStateException("No fragment to start activity"); @@ -103,8 +116,43 @@ public class NotificationAssistantPreferenceController extends TogglePreferenceC mNotificationBackend = backend; } + @VisibleForTesting + void getDefaultNASIntent() { + mDefaultNASComponent = mNotificationBackend.getDefaultNotificationAssistant(); + if (mDefaultNASComponent != null) { + mNASSettingIntent = new Intent( + NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS); + mNASSettingIntent.setPackage(mDefaultNASComponent.getPackageName()); + mNASSettingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } + } + @Override public boolean isSliceable() { return (mFragment != null && mFragment instanceof ConfigureNotificationSettings); } + + private boolean isNASSettingActivityAvailable() { + final List resolved = mPackageManager.queryIntentActivities(mNASSettingIntent, + PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL)); + return (resolved != null && !resolved.isEmpty()); + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + if (isNASSettingActivityAvailable()) { + preference.setIntent(mNASSettingIntent); + } else { + // Cannot find settings activity from the default NAS app + preference.setIntent(null); + preference.setOnPreferenceClickListener( + preference1 -> { + onPreferenceChange(preference1, !isChecked()); + ((PrimarySwitchPreference) preference1).setChecked(isChecked()); + return true; + } + ); + } + } } diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java index a198d86a814..54a7fb16eb6 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java @@ -22,7 +22,6 @@ import static org.robolectric.RuntimeEnvironment.application; import android.content.Intent; import android.hardware.fingerprint.FingerprintManager; -import android.widget.Button; import androidx.appcompat.app.AlertDialog; @@ -66,6 +65,23 @@ public class SetupFingerprintEnrollFindSensorTest { @Test public void fingerprintEnroll_showsAlert_whenClickingSkip() { + final AlertDialog alertDialog = setupAlertDialog(); + final ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf( + alertDialog); + final int titleRes = R.string.setup_fingerprint_enroll_skip_title; + + assertThat(application.getString(titleRes)).isEqualTo(shadowAlertDialog.getTitle()); + } + + @Test + public void fingerprintEnroll_showsAlert_setSudTheme() { + final AlertDialog alertDialog = setupAlertDialog(); + + assertThat(alertDialog.getContext().getThemeResId()).isEqualTo( + R.style.GlifV2ThemeAlertDialog); + } + + private AlertDialog setupAlertDialog() { final Intent intent = new Intent() // Set the challenge token so the confirm screen will not be shown .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]); @@ -80,9 +96,6 @@ public class SetupFingerprintEnrollFindSensorTest { final AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); assertThat(alertDialog).isNotNull(); - final ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf( - alertDialog); - final int titleRes = R.string.setup_fingerprint_enroll_skip_title; - assertThat(application.getString(titleRes)).isEqualTo(shadowAlertDialog.getTitle()); + return alertDialog; } } diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java index d1307114e65..b5946673815 100644 --- a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java @@ -16,7 +16,12 @@ package com.android.settings.notification; +import static android.service.notification.NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -29,16 +34,24 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Application; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.os.UserManager; import android.provider.Settings; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.testutils.shadow.ShadowSecureSettings; +import com.android.settingslib.PrimarySwitchPreference; import org.junit.Before; import org.junit.Test; @@ -47,9 +60,13 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; +import java.util.ArrayList; +import java.util.List; + @RunWith(RobolectricTestRunner.class) public class NotificationAssistantPreferenceControllerTest { @@ -67,23 +84,48 @@ public class NotificationAssistantPreferenceControllerTest { private NotificationBackend mBackend; @Mock private UserManager mUserManager; + @Mock + private PackageManager mPackageManager; private NotificationAssistantPreferenceController mPreferenceController; - ComponentName mNASComponent = new ComponentName("a", "b"); + ComponentName mNASComponent = new ComponentName("pkgname", "clsname"); + private PrimarySwitchPreference mPreference; + private ShadowApplication mShadowApplication; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(ApplicationProvider.getApplicationContext()); - ShadowApplication.getInstance().setSystemService(Context.USER_SERVICE, mUserManager); + mPreference = spy(new PrimarySwitchPreference(mContext)); + mShadowApplication = ShadowApplication.getInstance(); + mShadowApplication.setSystemService(Context.USER_SERVICE, mUserManager); doReturn(mContext).when(mFragment).getContext(); when(mFragment.getFragmentManager()).thenReturn(mFragmentManager); when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction); when(mBackend.getDefaultNotificationAssistant()).thenReturn(mNASComponent); + when(mContext.getPackageManager()).thenReturn(mPackageManager); mPreferenceController = new NotificationAssistantPreferenceController(mContext); mPreferenceController.setBackend(mBackend); mPreferenceController.setFragment(mFragment); + mPreferenceController.getDefaultNASIntent(); + + final PreferenceManager preferenceManager = new PreferenceManager(mContext); + final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext); + mPreference.setKey(NotificationAssistantPreferenceController.KEY_NAS); + screen.addPreference(mPreference); + mPreferenceController.displayPreference(screen); + when(mUserManager.getProfileIds(eq(0), anyBoolean())).thenReturn(new int[] {0, 10}); when(mUserManager.getProfileIds(eq(20), anyBoolean())).thenReturn(new int[] {20}); + + ActivityInfo activityInfo1 = new ActivityInfo(); + activityInfo1.packageName = "pkgname"; + activityInfo1.name = "name"; + ResolveInfo resolveInfo1 = new ResolveInfo(); + resolveInfo1.activityInfo = activityInfo1; + List resolvers1 = new ArrayList<>(); + resolvers1.add(resolveInfo1); + when(mPackageManager.queryIntentActivities(any(Intent.class), any())) + .thenReturn(resolvers1); } @Test @@ -108,6 +150,34 @@ public class NotificationAssistantPreferenceControllerTest { verify(mBackend, times(1)).setNotificationAssistantGranted(null); } + @Test + public void testUpdateState_SettingActivityAvailable() throws Exception { + mPreferenceController.updateState(mPreference); + assertNotNull(mPreference.getIntent()); + + mPreference.performClick(); + Intent nextIntent = Shadows.shadowOf( + (Application) ApplicationProvider.getApplicationContext()).getNextStartedActivity(); + assertEquals(nextIntent.getAction(), ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS); + } + + @Test + public void testUpdateState_SettingActivityUnavailable() throws Exception { + when(mPackageManager.queryIntentActivities(any(Intent.class), any())) + .thenReturn(null); + mPreferenceController.updateState(mPreference); + assertNull(mPreference.getIntent()); + + mPreference.performClick(); + Intent nextIntent = Shadows.shadowOf( + (Application) ApplicationProvider.getApplicationContext()).getNextStartedActivity(); + assertNull(nextIntent); + // Verify a dialog is shown + verify(mFragmentTransaction).add( + any(NotificationAssistantDialogFragment.class), anyString()); + verify(mBackend, times(0)).setNotificationAssistantGranted(any()); + } + @Test @Config(shadows = ShadowSecureSettings.class) public void testMigrationFromSetting_userEnable_multiProfile() throws Exception { diff --git a/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java index 526b6cc9e3e..805041c6736 100644 --- a/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java @@ -19,7 +19,6 @@ package com.android.settings.applications.appinfo; import static com.google.common.truth.Truth.assertThat; import android.content.Context; -import android.util.FeatureFlagUtils; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -49,22 +48,10 @@ public class AppLocalePreferenceControllerTest { return mCanDisplayLocaleUi; } }; - FeatureFlagUtils - .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, true); } @Test - public void getAvailabilityStatus_canShowUiButFeatureFlagOff_shouldReturnUnavailable() { - mCanDisplayLocaleUi = true; - FeatureFlagUtils - .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, false); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE); - } - - @Test - public void getAvailabilityStatus_canShowUiAndFeatureFlagOn_shouldReturnAvailable() { + public void getAvailabilityStatus_canShowUi_shouldReturnAvailable() { mCanDisplayLocaleUi = true; assertThat(mController.getAvailabilityStatus()) @@ -72,20 +59,10 @@ public class AppLocalePreferenceControllerTest { } @Test - public void getAvailabilityStatus_featureFlagOnButCanNotShowUi_shouldReturnUnavailable() { + public void getAvailabilityStatus_canNotShowUi_shouldReturnUnavailable() { mCanDisplayLocaleUi = false; assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE); } - - @Test - public void getAvailabilityStatus_featureFlagOffAndCanNotShowUi_shouldReturnUnavailable() { - mCanDisplayLocaleUi = false; - FeatureFlagUtils - .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, false); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE); - } } diff --git a/tests/unit/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceControllerTest.java deleted file mode 100644 index 648c7570304..00000000000 --- a/tests/unit/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceControllerTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2021 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.applications.appinfo; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.spy; - -import android.content.Context; -import android.util.FeatureFlagUtils; - -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; - - -import com.android.settings.core.BasePreferenceController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -public class ManageAppLocalePreferenceControllerTest { - private Context mContext; - private ManageAppLocalePreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(ApplicationProvider.getApplicationContext()); - mController = spy(new ManageAppLocalePreferenceController(mContext, "a key")); - - FeatureFlagUtils - .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, true); - } - - @Test - public void getAvailabilityStatus_featureFlagOff_shouldReturnUnavailable() { - FeatureFlagUtils - .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, false); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE); - } - - @Test - public void getAvailabilityStatus_featureFlagOn_shouldReturnAvailable() { - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.AVAILABLE); - } -} diff --git a/tests/unit/src/com/android/settings/localepicker/LocaleHelperPreferenceControllerTest.java b/tests/unit/src/com/android/settings/localepicker/LocaleHelperPreferenceControllerTest.java new file mode 100644 index 00000000000..31b8e794480 --- /dev/null +++ b/tests/unit/src/com/android/settings/localepicker/LocaleHelperPreferenceControllerTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2022 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 org.mockito.Mockito.anyString; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.os.Looper; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.settingslib.widget.FooterPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidJUnit4.class) +public class LocaleHelperPreferenceControllerTest { + private Context mContext; + private LocaleHelperPreferenceController mLocaleHelperPreferenceController; + + @Mock + private FooterPreference mMockFooterPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + if (Looper.myLooper() == null) { + Looper.prepare(); + } + mContext = ApplicationProvider.getApplicationContext(); + mLocaleHelperPreferenceController = new LocaleHelperPreferenceController(mContext); + } + + @Test + public void updateFooterPreference_setFooterPreference_hasClickAction() { + mLocaleHelperPreferenceController.updateFooterPreference(mMockFooterPreference); + verify(mMockFooterPreference).setLearnMoreText(anyString()); + } +}