From 85356adb942a5674ef3d2c6d4e19ecf6679c545b Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Sat, 22 Jan 2022 18:29:32 +0800 Subject: [PATCH 01/16] Fix EligibleCardChecker test failure Use a fake slice instead of a wifi slice to decouple the dependency. Fixes: 215046603 Test: robotest Change-Id: I02da766007c5bb096dc0844f9ea62d0b49e1f4d6 --- .../EligibleCardCheckerTest.java | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java index e63dd80a799..64dbbb28728 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java @@ -24,20 +24,26 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; +import android.app.Activity; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.net.Uri; +import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.SliceProvider; import androidx.slice.widget.SliceLiveData; +import androidx.slice.builders.ListBuilder; +import androidx.slice.builders.SliceAction; +import com.android.settings.R; import com.android.settings.slices.CustomSliceRegistry; -import com.android.settings.wifi.slice.ContextualWifiSlice; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @@ -48,6 +54,7 @@ public class EligibleCardCheckerTest { private Context mContext; private EligibleCardChecker mEligibleCardChecker; + private Activity mActivity; @Before public void setUp() { @@ -55,22 +62,19 @@ public class EligibleCardCheckerTest { mEligibleCardChecker = spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI))); SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + mActivity = Robolectric.buildActivity(Activity.class).create().get(); } @Test - @Ignore public void isSliceToggleable_cardWithToggle_returnTrue() { - final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext); - final Slice slice = wifiSlice.getSlice(); + final Slice slice = buildSlice(); assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isTrue(); } @Test - @Ignore public void isCardEligibleToDisplay_toggleSlice_hasInlineActionShouldBeTrue() { - final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext); - final Slice slice = wifiSlice.getSlice(); + final Slice slice = buildSlice(); doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class)); mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)); @@ -118,10 +122,8 @@ public class EligibleCardCheckerTest { } @Test - @Ignore public void isCardEligibleToDisplay_sliceNotNull_cacheSliceToCard() { - final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext); - final Slice slice = wifiSlice.getSlice(); + final Slice slice = buildSlice(); doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class)); mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)); @@ -137,4 +139,23 @@ public class EligibleCardCheckerTest { .setSliceUri(sliceUri) .build(); } + + private Slice buildSlice() { + final String title = "test_title"; + final IconCompat icon = IconCompat.createWithResource(mActivity, R.drawable.empty_icon); + final PendingIntent pendingIntent = PendingIntent.getActivity( + mActivity, + title.hashCode() /* requestCode */, + new Intent("test action"), + PendingIntent.FLAG_IMMUTABLE); + final SliceAction action + = SliceAction.createDeeplink(pendingIntent, icon, ListBuilder.SMALL_IMAGE, title); + return new ListBuilder(mActivity, TEST_SLICE_URI, ListBuilder.INFINITY) + .addRow(new ListBuilder.RowBuilder() + .addEndItem(icon, ListBuilder.ICON_IMAGE) + .setTitle(title) + .setPrimaryAction(action)) + .addAction(SliceAction.createToggle(pendingIntent, null /* actionTitle */, true)) + .build(); + } } From c7b568751eed4e9f8f4056848e8894c6abb2860f Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Wed, 9 Feb 2022 21:34:59 +0800 Subject: [PATCH 02/16] Use Intent.EXTRA_USER for ACTION_CHANGE_DEFAULT Use Intent.EXTRA_USER to pass the UserHandle as the extra field of ACTION_CHANGE_DEFAULT. Bug: 215300017 Test: manual Change-Id: I8862ae509638c7c264f49c4bc5753a65e8fdcfbc --- src/com/android/settings/nfc/PaymentDefaultDialog.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java index a888167b899..75746ce94d2 100644 --- a/src/com/android/settings/nfc/PaymentDefaultDialog.java +++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java @@ -58,7 +58,11 @@ public final class PaymentDefaultDialog extends AlertActivity implements ComponentName component = intent.getParcelableExtra( CardEmulation.EXTRA_SERVICE_COMPONENT); String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY); - int userId = intent.getIntExtra(CardEmulation.EXTRA_USERID, UserHandle.myUserId()); + UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER); + if (userHandle == null) { + userHandle = UserHandle.CURRENT; + } + int userId = userHandle.getIdentifier(); setResult(RESULT_CANCELED); if (!buildDialog(component, category, userId)) { From 2353147905418eaa5877e79af38ee3c7fbd5aeeb Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Tue, 8 Feb 2022 17:23:35 +0800 Subject: [PATCH 03/16] [Settings] Fix the test fail in robo tests Bug: 215047192 Test: make RunSettingsRoboTests ROBOTEST_FILTER=MobileNetworkSummaryControllerTest Change-Id: Iea894d989a3f255085cbf280619e28b65553658a --- .../MobileNetworkSummaryControllerTest.java | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java index fc6481b8cc4..dcf086c68fb 100644 --- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java @@ -44,6 +44,8 @@ import androidx.lifecycle.Lifecycle; import androidx.preference.PreferenceScreen; import com.android.settings.Settings.MobileNetworkActivity; +import com.android.settings.network.helper.SubscriptionAnnotation; +import com.android.settings.network.helper.SubscriptionGrouping; import com.android.settings.widget.AddPreference; import com.android.settingslib.RestrictedLockUtils; @@ -123,7 +125,6 @@ public class MobileNetworkSummaryControllerTest { @Test - @Ignore public void getSummary_noSubscriptions_correctSummaryAndClickHandler() { mController.displayPreference(mPreferenceScreen); mController.onResume(); @@ -211,23 +212,6 @@ public class MobileNetworkSummaryControllerTest { SubscriptionManager.INVALID_SUBSCRIPTION_ID)).isEqualTo(sub1.getSubscriptionId()); } - @Test - @Ignore - public void getSummary_providerModel_Enabled() { - final SubscriptionInfo sub1 = mock(SubscriptionInfo.class); - final SubscriptionInfo sub2 = mock(SubscriptionInfo.class); - when(sub1.getSubscriptionId()).thenReturn(1); - when(sub2.getSubscriptionId()).thenReturn(2); - when(sub1.getDisplayName()).thenReturn("sub1"); - when(sub2.getDisplayName()).thenReturn("sub2"); - - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); - SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); - mController.displayPreference(mPreferenceScreen); - mController.onResume(); - assertThat(mController.getSummary()).isEqualTo("sub1, sub2"); - } - @Test public void addButton_noSubscriptionsNoEuiccMgr_noAddClickListener() { when(mEuiccManager.isEnabled()).thenReturn(false); @@ -319,7 +303,6 @@ public class MobileNetworkSummaryControllerTest { } @Test - @Ignore public void onAirplaneModeChanged_oneSubscriptionAirplaneModeGetsTurnedOn_isDisabled() { final SubscriptionInfo sub1 = mock(SubscriptionInfo.class); SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); From 2cb3f925a3cb605e319d7894d9b77c42db4550f1 Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Mon, 24 Jan 2022 10:35:06 +0800 Subject: [PATCH 04/16] Only set embedding rule for top level injection Only the injected items on the top level pages should always be opened on the right pane, so we should only register the split rule for that part. This will leave flexibilities for those injected items in the subpages. Fixes: 216026158 Test: Go to Passwords & accounts > {account} > Google Account and see the page opened in a full screen/new task. Change-Id: I9f311547854ace410e93fdb4ca394df1079f723c --- .../dashboard/DashboardFeatureProviderImpl.java | 17 +++++++---------- .../profileselector/ProfileSelectDialog.java | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index cdac3b9f41d..8ad66d23e4f 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -171,11 +171,13 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { intent.setAction(action); } // Register the rule for injected apps. - ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome( - mContext, - new ComponentName(tile.getPackageName(), tile.getComponentName()), - action, - true /* clearTop */); + if (fragment instanceof TopLevelSettings) { + ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome( + mContext, + new ComponentName(tile.getPackageName(), tile.getComponentName()), + action, + true /* clearTop */); + } pref.setOnPreferenceClickListener(preference -> { TopLevelHighlightMixin highlightMixin = null; if (fragment instanceof TopLevelSettings @@ -442,11 +444,6 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile); mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory); - //TODO(b/201970810): Add test cases. - if (tile.isNewTask(mContext)) { - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - } - if (tile.userHandle == null || tile.isPrimaryProfileOnly()) { activity.startActivity(intent); } else if (tile.userHandle.size() == 1) { diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java index e0ba3787199..d3234dd1151 100644 --- a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java +++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java @@ -97,7 +97,7 @@ public class ProfileSelectDialog extends DialogFragment implements OnClickListen public void onClick(DialogInterface dialog, int which) { final UserHandle user = mSelectedTile.userHandle.get(which); // Show menu on top level items. - final Intent intent = mSelectedTile.getIntent(); + final Intent intent = new Intent(mSelectedTile.getIntent()); FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider() .logStartedIntentWithProfile(intent, mSourceMetricCategory, which == 1 /* isWorkProfile */); From 5f03fad2d370ee1b048e33930fc5c4fd8a45e137 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 11 Feb 2022 11:40:08 +0000 Subject: [PATCH 05/16] Switch "UTC time" to "Unix epoch time" This is more correct. Android devices, even under ideal conditions, don't track UTC (which contains leap seconds and uses the SI definition of a second) but use a clock based on Unix epoch time (no leap seconds, but clocks may skip/stop or smear around leap seconds to ensure a fixed number of second increments per calendar day when leap seconds are applied to UTC). Bug: 218802673 Test: Compile only Change-Id: I4c5435bdb3bb124d4cb465a966bd43d58b640421 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index a829847bed7..92427cf7d60 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -597,7 +597,7 @@ Set date and time Set date, time, time zone, & formats - + Set time automatically Set time zone automatically From 3eb4cb41ae2ed42772439f16e16dfdba4dc51d69 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 10 Feb 2022 15:38:52 +0000 Subject: [PATCH 06/16] Move Dream OOBE activity to SettingsGoogle This will only be used on pixel devices. Bug: 217555049 Test: locally on device Change-Id: Ica7cddae8b8b8693a83da95d25a8d0827aed0945 --- AndroidManifest.xml | 18 -- res/layout/dream_setup_layout.xml | 39 ---- .../dream/AutoFitGridLayoutManager.java | 4 +- .../android/settings/dream/DreamAdapter.java | 4 +- .../settings/dream/DreamSetupActivity.java | 177 ------------------ .../android/settings/dream/IDreamItem.java | 5 +- 6 files changed, 8 insertions(+), 239 deletions(-) delete mode 100644 res/layout/dream_setup_layout.xml delete mode 100644 src/com/android/settings/dream/DreamSetupActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fcd6cc07273..6857927ad98 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2920,24 +2920,6 @@ android:value="true" /> - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/android/settings/dream/AutoFitGridLayoutManager.java b/src/com/android/settings/dream/AutoFitGridLayoutManager.java index 0e5d3e1bbd5..7de0eaead72 100644 --- a/src/com/android/settings/dream/AutoFitGridLayoutManager.java +++ b/src/com/android/settings/dream/AutoFitGridLayoutManager.java @@ -24,10 +24,10 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; /** Grid layout manager that calculates the number of columns for the screen size. */ -final class AutoFitGridLayoutManager extends GridLayoutManager { +public final class AutoFitGridLayoutManager extends GridLayoutManager { private final float mColumnWidth; - AutoFitGridLayoutManager(Context context) { + public AutoFitGridLayoutManager(Context context) { super(context, /* spanCount= */ 1); this.mColumnWidth = context .getResources() diff --git a/src/com/android/settings/dream/DreamAdapter.java b/src/com/android/settings/dream/DreamAdapter.java index e6745464ed2..8d0e9d5d297 100644 --- a/src/com/android/settings/dream/DreamAdapter.java +++ b/src/com/android/settings/dream/DreamAdapter.java @@ -37,7 +37,7 @@ import java.util.List; /** * RecyclerView adapter which displays list of items for the user to select. */ -class DreamAdapter extends RecyclerView.Adapter { +public class DreamAdapter extends RecyclerView.Adapter { private final List mItemList; private int mLastSelectedPos = -1; @@ -103,7 +103,7 @@ class DreamAdapter extends RecyclerView.Adapter { } } - DreamAdapter(List itemList) { + public DreamAdapter(List itemList) { mItemList = itemList; } diff --git a/src/com/android/settings/dream/DreamSetupActivity.java b/src/com/android/settings/dream/DreamSetupActivity.java deleted file mode 100644 index 6a126713686..00000000000 --- a/src/com/android/settings/dream/DreamSetupActivity.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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.dream; - -import android.app.settings.SettingsEnums; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.recyclerview.widget.RecyclerView; - -import com.android.settings.R; -import com.android.settings.SettingsActivity; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settingslib.dream.DreamBackend; - -import com.google.android.setupcompat.template.FooterBarMixin; -import com.google.android.setupcompat.template.FooterButton; -import com.google.android.setupcompat.util.WizardManagerHelper; -import com.google.android.setupdesign.GlifLayout; -import com.google.android.setupdesign.util.ThemeHelper; -import com.google.android.setupdesign.util.ThemeResolver; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * The setup activity for dreams which is displayed during setup wizard. - */ -public class DreamSetupActivity extends SettingsActivity { - @Override - public Intent getIntent() { - Intent modIntent = new Intent(super.getIntent()); - modIntent.putExtra(EXTRA_SHOW_FRAGMENT, DreamSetupFragment.class.getName()); - return modIntent; - } - - @Override - protected boolean isValidFragment(String fragmentName) { - return DreamSetupFragment.class.getName().equals(fragmentName); - } - - @Override - protected void onCreate(Bundle savedInstance) { - setTheme(ThemeResolver.getDefault().resolve(getIntent())); - ThemeHelper.trySetDynamicColor(this); - super.onCreate(savedInstance); - } - - @Override - protected boolean isToolbarEnabled() { - return false; - } - - /** - * Fragment used to control the active dream. - */ - public static class DreamSetupFragment extends SettingsPreferenceFragment { - private DreamBackend mBackend; - private DreamBackend.DreamInfo mActiveDream; - private FooterButton mFooterButton; - - @Override - public int getMetricsCategory() { - return SettingsEnums.DREAM; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.dream_setup_layout, container, false); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - mBackend = DreamBackend.getInstance(getContext()); - final List dreamInfos = mBackend.getDreamInfos(); - mActiveDream = dreamInfos.stream().filter(d -> d.isActive).findFirst().orElse(null); - DreamAdapter dreamAdapter = new DreamAdapter(dreamInfos.stream() - .map(DreamItem::new) - .collect(Collectors.toList())); - - final RecyclerView recyclerView = view.findViewById(R.id.dream_setup_list); - recyclerView.setLayoutManager(new AutoFitGridLayoutManager(getContext())); - recyclerView.setHasFixedSize(true); - recyclerView.setAdapter(dreamAdapter); - - final GlifLayout layout = view.findViewById(R.id.setup_wizard_layout); - final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class); - mFooterButton = new FooterButton.Builder(getContext()) - .setListener(this::onPrimaryButtonClicked) - .setButtonType(FooterButton.ButtonType.NEXT) - .setTheme(R.style.SudGlifButton_Primary) - .build(); - updateFooterButtonText(); - mixin.setPrimaryButton(mFooterButton); - } - - private void updateFooterButtonText() { - final int res = canCustomizeDream() ? R.string.wizard_next : R.string.wizard_finish; - mFooterButton.setText(getContext().getString(res)); - } - - private boolean canCustomizeDream() { - return mActiveDream != null && mActiveDream.settingsComponentName != null; - } - - private void onPrimaryButtonClicked(View view) { - if (canCustomizeDream()) { - final Intent intent = new Intent().setComponent(mActiveDream.settingsComponentName); - WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent); - startActivity(intent); - } - - // Use RESULT_CANCELED here so that the user may go back and change this if they wish. - setResult(RESULT_CANCELED); - finish(); - } - - private class DreamItem implements IDreamItem { - private final DreamBackend.DreamInfo mDreamInfo; - - private DreamItem(DreamBackend.DreamInfo dreamInfo) { - mDreamInfo = dreamInfo; - } - - @Override - public CharSequence getTitle() { - return mDreamInfo.caption; - } - - @Override - public Drawable getIcon() { - return mDreamInfo.icon; - } - - @Override - public void onItemClicked() { - mActiveDream = mDreamInfo; - mBackend.setActiveDream(mDreamInfo.componentName); - updateFooterButtonText(); - } - - @Override - public Drawable getPreviewImage() { - return mDreamInfo.previewImage; - } - - @Override - public boolean isActive() { - if (mActiveDream == null) { - return false; - } - return mDreamInfo.componentName.equals(mActiveDream.componentName); - } - } - } -} diff --git a/src/com/android/settings/dream/IDreamItem.java b/src/com/android/settings/dream/IDreamItem.java index 66528575eec..c462fe25502 100644 --- a/src/com/android/settings/dream/IDreamItem.java +++ b/src/com/android/settings/dream/IDreamItem.java @@ -18,7 +18,10 @@ package com.android.settings.dream; import android.graphics.drawable.Drawable; -interface IDreamItem { +/** + * Interface representing a dream item to be displayed. + */ +public interface IDreamItem { CharSequence getTitle(); Drawable getIcon(); From 0f384398b48f27052f9f03f027a705cadda02cd0 Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Sun, 13 Feb 2022 15:50:27 +0800 Subject: [PATCH 07/16] Polish and humanize the summary for the High Contrast Text. - Add new summary string. Bug: 219163254 Test: manual test Change-Id: I4902452b1c0f53e8e6a74b8529139a2d7c1cdeaf --- res/values/strings.xml | 2 ++ res/xml/accessibility_text_reading_options.xml | 1 + 2 files changed, 3 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 36e1193e3ed..310b3b162e9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5386,6 +5386,8 @@ Non-transparent High contrast text + + Change text color to black or white. Maximizes contrast with the background. Auto update screen magnification diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml index 7d815653e19..d55882d2011 100644 --- a/res/xml/accessibility_text_reading_options.xml +++ b/res/xml/accessibility_text_reading_options.xml @@ -54,6 +54,7 @@ Date: Sat, 12 Feb 2022 09:13:40 +0800 Subject: [PATCH 08/16] Polish humanize strings for Accessibility timeout page - Add intro for purpose or behavior - Update footer description on usage, availability, or limitations - Remove the divider below illustration Bug: 218408807 Test: Manual testing Change-Id: Ibb19da2624c1d5cc8073df4fefb902c2c20a3d72 --- res/values/strings.xml | 4 +++- res/xml/accessibility_control_timeout_settings.xml | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 82bccee92b7..0e4a64193eb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5426,7 +5426,9 @@ Time to take action - Choose how long to show messages that ask you to take action, but are visible only temporarily.\n\nNot all apps support this setting. + This timing preference isn\u2019t supported by all apps + + Choose how long to show temporary messages that ask you to take action Touch & hold delay diff --git a/res/xml/accessibility_control_timeout_settings.xml b/res/xml/accessibility_control_timeout_settings.xml index aaa2c0682de..3cd0dd63e63 100644 --- a/res/xml/accessibility_control_timeout_settings.xml +++ b/res/xml/accessibility_control_timeout_settings.xml @@ -21,6 +21,11 @@ android:title="@string/accessibility_control_timeout_preference_title" android:persistent="false" > + + @@ -28,7 +33,6 @@ Date: Sat, 12 Feb 2022 09:36:42 +0800 Subject: [PATCH 09/16] Polish humanize strings for Accessibility autoclick page - Add intro for purpose or behavior - Update footer description on usage, availability, or limitations - Remove the divider below illustration - Remove custom divider Bug: 218409017 Test: Manual testing Change-Id: I45ab1d06bf4f49ab48a820aedfc89eafc24b17fe --- res/values/strings.xml | 8 +++++--- res/xml/accessibility_autoclick_settings.xml | 10 ++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 82bccee92b7..46ecc4d9782 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5453,10 +5453,12 @@ About autoclick (dwell timing) Learn more about autoclick (dwell timing) - - Autoclick works with a connected mouse. You can set the mouse cursor to click automatically when the cursor stops moving for a certain amount of time. + + You can set a connected mouse to click automatically when the cursor stops moving for a certain amount of time + + Autoclick can be helpful if clicking the mouse is difficult - Off + Autoclick off Short diff --git a/res/xml/accessibility_autoclick_settings.xml b/res/xml/accessibility_autoclick_settings.xml index 617f22a94b1..943bc67b478 100644 --- a/res/xml/accessibility_autoclick_settings.xml +++ b/res/xml/accessibility_autoclick_settings.xml @@ -19,18 +19,21 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/accessibility_autoclick_preference_title"> + + + android:title="@string/accessibility_autoclick_default_title" /> Date: Sun, 13 Feb 2022 12:59:52 +0800 Subject: [PATCH 10/16] Polish humanize strings for color inversion page - Add intro for purpose or behavior - Update footer description on usage, availability, or limitations Bug: 218408568 Test: Manual testing Change-Id: Iceb35f2673ca5cd69093811a8ecc7c28579281f1 --- res/values/strings.xml | 11 ++++++----- .../ToggleColorInversionPreferenceFragment.java | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 82bccee92b7..79456084607 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5436,14 +5436,15 @@ Use color inversion Color inversion shortcut + + Color inversion turns light screens dark. It also turns dark screens light. -
- Note: + Keep in mind
    -
  1. \u00a0Color inversion also turns dark screens light.
  2. -
  3. \u00a0Colors will change in media and images.
  4. -
  5. \u00a0Dark theme can be used to display a dark background. Dark theme works with supported apps. Color inversion works on all apps.
  6. +
  7. \u00a0Colors will change in media and images
  8. +
  9. \u00a0Color inversion works on all apps
  10. +
  11. \u00a0To display a dark background, Dark theme can be used instead
]]>
diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java index 679e28424e3..e4216265650 100644 --- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java @@ -82,6 +82,7 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere mComponentName = COLOR_INVERSION_COMPONENT_NAME; mPackageName = getText(R.string.accessibility_display_inversion_preference_title); mHtmlDescription = getText(R.string.accessibility_display_inversion_preference_subtitle); + mTopIntroTitle = getText(R.string.accessibility_display_inversion_preference_intro_text); mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) .authority(getPrefContext().getPackageName()) .appendPath(String.valueOf(R.raw.accessibility_color_inversion_banner)) From 4af8439e667fb15aa8ed714e88fddb8cc4a2de46 Mon Sep 17 00:00:00 2001 From: menghanli Date: Sun, 13 Feb 2022 13:15:26 +0800 Subject: [PATCH 11/16] Polish humanize strings for extra dim page - Add intro for purpose or behavior - Update footer description on usage, availability, or limitations Bug: 218408553 Test: Manual testing Change-Id: I3951959263e30e7525a44950c38374366eaf69c7 --- res/values/strings.xml | 8 ++++---- .../ToggleReduceBrightColorsPreferenceFragment.java | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 82bccee92b7..9cb2eeb4031 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5617,10 +5617,11 @@ Dim screen beyond your phone\u2019s minimum brightness Dim screen beyond your tablet\u2019s minimum brightness + + Make your screen dimmer so it\u2019s more comfortable to read -
- This can be helpful when: +
  • \u00a0Your phone\u2019s default minimum brightness is still too bright
  • \u00a0You\u2019re using your phone in dark situations, like at night or in a dark room before bed
  • @@ -5629,8 +5630,7 @@
    -
    - This can be helpful when: +
  • \u00a0Your tablet\u2019s default minimum brightness is still too bright
  • \u00a0You\u2019re using your tablet in dark situations, like at night or in a dark room before bed
  • diff --git a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java index 973e27cd616..1e2e9e56909 100644 --- a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java @@ -68,6 +68,7 @@ public class ToggleReduceBrightColorsPreferenceFragment extends ToggleFeaturePre mComponentName = REDUCE_BRIGHT_COLORS_COMPONENT_NAME; mPackageName = getText(R.string.reduce_bright_colors_preference_title); mHtmlDescription = getText(R.string.reduce_bright_colors_preference_subtitle); + mTopIntroTitle = getText(R.string.reduce_bright_colors_preference_intro_text); mRbcIntensityPreferenceController = new ReduceBrightColorsIntensityPreferenceController(getContext(), KEY_INTENSITY); mRbcPersistencePreferenceController = From 27e442ded7e0f49e4c412ff632ee1c20f760ca33 Mon Sep 17 00:00:00 2001 From: menghanli Date: Sun, 13 Feb 2022 14:12:06 +0800 Subject: [PATCH 12/16] Polish humanize strings for color correction page - Add intro for purpose or behavior - Remove correction mode category title - Reformat deuteranomaly, protanomaly, and tritanomaly title and summary Bug: 218408547 Test: Manual testing Change-Id: I0cca0c063ab15b4065c0e3a277181a8cf44a70ce --- res/values/strings.xml | 18 ++++---- res/xml/accessibility_daltonizer_settings.xml | 43 ++++++++----------- .../ToggleDaltonizerPreferenceFragment.java | 12 +++++- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 82bccee92b7..5984d007ae8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5509,6 +5509,10 @@ %1$s added to Quick Settings. Swipe down to turn it on or off anytime. Dismiss + + Adjust how colors display on your phone + + Adjust how colors display on your tablet Use color correction @@ -5588,22 +5592,20 @@ Show in Quick Settings - - Correction mode - Deuteranomaly + Red-green - Protanomaly + Red-green - Tritanomaly + Blue-yellow Grayscale - Red-green + Green weak, deuteranomaly - Red-green + Red weak, protanomaly - Blue-yellow + Tritanomaly Extra dim diff --git a/res/xml/accessibility_daltonizer_settings.xml b/res/xml/accessibility_daltonizer_settings.xml index 1b69dc671bc..91b163bf68c 100644 --- a/res/xml/accessibility_daltonizer_settings.xml +++ b/res/xml/accessibility_daltonizer_settings.xml @@ -28,32 +28,27 @@ settings:allowDividerBelow="true" settings:searchable="false"/> - + - + - + - - - - + diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java index 5d9cbe57ee1..b1b9f81cb78 100644 --- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java @@ -51,7 +51,10 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED; private static final String KEY_PREVIEW = "daltonizer_preview"; - private static final String KEY_CATEGORY_MODE = "daltonizer_mode_category"; + private static final String KEY_DEUTERANOMALY = "daltonizer_mode_deuteranomaly"; + private static final String KEY_PROTANOMALY = "daltonizer_mode_protanomaly"; + private static final String KEY_TRITANOMEALY = "daltonizer_mode_tritanomaly"; + private static final String KEY_GRAYSCALE = "daltonizer_mode_grayscale"; private static final List sControllers = new ArrayList<>(); private static List buildPreferenceControllers(Context context, @@ -82,6 +85,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe mComponentName = DALTONIZER_COMPONENT_NAME; mPackageName = getText(R.string.accessibility_display_daltonizer_preference_title); mHtmlDescription = getText(R.string.accessibility_display_daltonizer_preference_subtitle); + mTopIntroTitle = getText(R.string.accessibility_daltonizer_about_intro_text); final View view = super.onCreateView(inflater, container, savedInstanceState); updateFooterPreference(); return view; @@ -111,9 +115,13 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe /** Customizes the order by preference key. */ protected List getPreferenceOrderList() { final List lists = new ArrayList<>(); + lists.add(KEY_TOP_INTRO_PREFERENCE); lists.add(KEY_PREVIEW); lists.add(KEY_USE_SERVICE_PREFERENCE); - lists.add(KEY_CATEGORY_MODE); + lists.add(KEY_DEUTERANOMALY); + lists.add(KEY_PROTANOMALY); + lists.add(KEY_TRITANOMEALY); + lists.add(KEY_GRAYSCALE); lists.add(KEY_GENERAL_CATEGORY); lists.add(KEY_HTML_DESCRIPTION_PREFERENCE); return lists; From 0a85c12fcaaae000f16d5c3eb9e6ddba560a0518 Mon Sep 17 00:00:00 2001 From: menghanli Date: Sun, 13 Feb 2022 13:26:43 +0800 Subject: [PATCH 13/16] Polish humanize strings for magnification page - Add intro for purpose or behavior - Update footer description on usage, availability, or limitations Bug: 218409016 Test: Manual testing Change-Id: I1259fc330caab304cc4ec22778e6a3e3ae13f269 --- res/values/strings.xml | 13 ++++++++----- .../MagnificationGesturesPreferenceController.java | 5 ++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 82bccee92b7..48f42593fba 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5246,9 +5246,11 @@ Tap 3 times to zoom Tap a button to zoom + + Quickly zoom in on the screen to make content larger -
    + To zoom in:
    {0,number,integer}. Use shortcut to start magnification
    {1,number,integer}. Tap the screen
    @@ -5256,10 +5258,11 @@ {3,number,integer}. Pinch with 2 fingers to adjust zoom
    {4,number,integer}. Use shortcut to stop magnification

    To zoom in temporarily:
    - {0,number,integer}. Use shortcut to start magnification
    - {1,number,integer}. Touch & hold anywhere on the screen
    - {2,number,integer}. Drag finger to move around screen
    - {3,number,integer}. Lift finger to stop magnification + {0,number,integer}. Make sure your magnification type is set to full screen
    + {1,number,integer}. Use shortcut to start magnification
    + {2,number,integer}. Touch & hold anywhere on the screen
    + {3,number,integer}. Drag finger to move around screen
    + {4,number,integer}. Lift finger to stop magnification ]]>
    diff --git a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java index 37d09a70a99..01ee249cc2d 100644 --- a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java +++ b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java @@ -100,7 +100,10 @@ public class MagnificationGesturesPreferenceController extends TogglePreferenceC extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES, R.string.accessibility_screen_magnification_gestures_title); - String summary = context.getString(R.string.accessibility_screen_magnification_summary); + String intro = context.getString(R.string.accessibility_screen_magnification_intro_text); + extras.putCharSequence(AccessibilitySettings.EXTRA_INTRO, intro); + + String summary = context.getString(R.string.accessibility_screen_magnification_summary); final Object[] numberArguments = {1, 2, 3, 4, 5}; summary = MessageFormat.format(summary, numberArguments); extras.putCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, summary); From cfc5554068c627d19225709d070b34bb19343d12 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Sat, 22 Jan 2022 03:20:24 +0800 Subject: [PATCH 14/16] [Panlingual] Add device default language to suggested group - Add default language preference - Polish unit test - Fix unsupported locale show on suggested group Bug: 209728327 Test: local test Test: atest pass Change-Id: I69778cb8d69b21314c75689f0d61c25294c7f9d2 --- res/values/strings.xml | 6 + res/xml/app_locale_details.xml | 9 +- .../appinfo/AppLocaleDetails.java | 177 +++++++++------ .../appinfo/AppLocaleDetailsTest.java | 211 ++++++++++++++---- 4 files changed, 291 insertions(+), 112 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index f071f5dd9c1..f5a3d6f1b31 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -491,6 +491,12 @@ All languages + + System language + + + System default - %1$s + The app is set to %1$s by default and doesn\u2019t support multiple languages. diff --git a/res/xml/app_locale_details.xml b/res/xml/app_locale_details.xml index 8056cbf2784..40ca58243ec 100644 --- a/res/xml/app_locale_details.xml +++ b/res/xml/app_locale_details.xml @@ -28,7 +28,14 @@ + android:title="@string/suggested_app_locales_title" > + + + + mSuggestedLocales = new ArrayList<>(); - private Collection mSupportedLocales = new ArrayList<>(); + private Collection mProcessedSuggestedLocales = new ArrayList<>(); + private Collection mProcessedSupportedLocales = new ArrayList<>(); + + private Collection mAppSupportedLocales = new ArrayList<>(); AppLocaleDetailsHelper(Context context, String packageName) { mContext = context; mPackageName = packageName; mTelephonyManager = context.getSystemService(TelephonyManager.class); mLocaleManager = context.getSystemService(LocaleManager.class); + mAppSupportedLocales = getAppSupportedLocales(); } /** Handle suggested and supported locales for UI display. */ @@ -225,49 +261,47 @@ public class AppLocaleDetails extends AppInfoBase implements RadioButtonPreferen /** Gets suggested locales in the app. */ public Collection getSuggestedLocales() { - return mSuggestedLocales; + return mProcessedSuggestedLocales; } /** Gets supported locales in the app. */ public Collection getSupportedLocales() { - return mSupportedLocales; + return mProcessedSupportedLocales; } @VisibleForTesting void handleSuggestedLocales() { - LocaleList currentSystemLocales = getCurrentSystemLocales(); Locale appLocale = getAppDefaultLocale(mContext, mPackageName); + // 1st locale in suggested languages group. + for (Locale supportedlocale : mAppSupportedLocales) { + if (compareLocale(supportedlocale, appLocale)) { + mProcessedSuggestedLocales.add(appLocale); + break; + } + } + + // 2nd and 3rd locale in suggested languages group. String simCountry = mTelephonyManager.getSimCountryIso().toUpperCase(Locale.US); String networkCountry = mTelephonyManager.getNetworkCountryIso().toUpperCase(Locale.US); - // 1st locale in suggested languages group. - if (appLocale != null) { - mSuggestedLocales.add(appLocale); - } - // 2nd locale in suggested languages group. - final List localeInfos = LocalePicker.getAllAssetLocales(mContext, false); - for (LocaleInfo localeInfo : localeInfos) { - Locale locale = localeInfo.getLocale(); - String localeCountry = locale.getCountry().toUpperCase(Locale.US); - if (!compareLocale(locale, appLocale) + mAppSupportedLocales.forEach(supportedlocale -> { + String localeCountry = supportedlocale.getCountry().toUpperCase(Locale.US); + if (!compareLocale(supportedlocale, appLocale) && isCountrySuggestedLocale(localeCountry, simCountry, networkCountry)) { - mSuggestedLocales.add(locale); + mProcessedSuggestedLocales.add(supportedlocale); } - } + }); + // Other locales in suggested languages group. - for (int i = 0; i < currentSystemLocales.size(); i++) { - Locale locale = currentSystemLocales.get(i); - boolean isInSuggestedLocales = false; - for (int j = 0; j < mSuggestedLocales.size(); j++) { - Locale suggestedLocale = Iterables.get(mSuggestedLocales, j); - if (compareLocale(locale, suggestedLocale)) { - isInSuggestedLocales = true; - break; + Collection supportedSystemLocales = new ArrayList<>(); + getCurrentSystemLocales().forEach(systemLocale -> { + mAppSupportedLocales.forEach(supportedLocale -> { + if (compareLocale(systemLocale, supportedLocale)) { + supportedSystemLocales.add(supportedLocale); } - } - if (!isInSuggestedLocales) { - mSuggestedLocales.add(locale); - } - } + }); + }); + supportedSystemLocales.removeAll(mProcessedSuggestedLocales); + mProcessedSuggestedLocales.addAll(supportedSystemLocales); } @VisibleForTesting @@ -290,26 +324,34 @@ public class AppLocaleDetails extends AppInfoBase implements RadioButtonPreferen @VisibleForTesting void handleSupportedLocales() { - LocaleList localeList = getPackageLocales(); - if (localeList == null) { - String[] languages = getAssetSystemLocales(); - for (String language : languages) { - mSupportedLocales.add(Locale.forLanguageTag(language)); - } - } else { - for (int i = 0; i < localeList.size(); i++) { - mSupportedLocales.add(localeList.get(i)); - } - } + mProcessedSupportedLocales.addAll(mAppSupportedLocales); - if (mSuggestedLocales != null || !mSuggestedLocales.isEmpty()) { - mSupportedLocales.removeAll(mSuggestedLocales); + if (mProcessedSuggestedLocales != null || !mProcessedSuggestedLocales.isEmpty()) { + mProcessedSuggestedLocales.retainAll(mProcessedSupportedLocales); + mProcessedSupportedLocales.removeAll(mProcessedSuggestedLocales); } } private void clearLocalesData() { - mSuggestedLocales.clear(); - mSupportedLocales.clear(); + mProcessedSuggestedLocales.clear(); + mProcessedSupportedLocales.clear(); + } + + private Collection getAppSupportedLocales() { + Collection appSupportedLocales = new ArrayList<>(); + LocaleList localeList = getPackageLocales(); + + if (localeList != null && localeList.size() > 0) { + for (int i = 0; i < localeList.size(); i++) { + appSupportedLocales.add(localeList.get(i)); + } + } else { + String[] languages = getAssetLocales(); + for (String language : languages) { + appSupportedLocales.add(Locale.forLanguageTag(language)); + } + } + return appSupportedLocales; } /** Gets per app's default locale */ @@ -317,8 +359,8 @@ public class AppLocaleDetails extends AppInfoBase implements RadioButtonPreferen LocaleManager localeManager = context.getSystemService(LocaleManager.class); try { LocaleList localeList = (localeManager == null) - ? new LocaleList() : localeManager.getApplicationLocales(packageName); - return localeList.isEmpty() ? null : localeList.get(0); + ? null : localeManager.getApplicationLocales(packageName); + return localeList == null ? null : localeList.get(0); } catch (IllegalArgumentException e) { Log.w(TAG, "package name : " + packageName + " is not correct. " + e); } @@ -344,12 +386,17 @@ public class AppLocaleDetails extends AppInfoBase implements RadioButtonPreferen } @VisibleForTesting - LocaleList getCurrentSystemLocales() { - return Resources.getSystem().getConfiguration().getLocales(); + Collection getCurrentSystemLocales() { + LocaleList localeList = Resources.getSystem().getConfiguration().getLocales(); + Collection systemLocales = new ArrayList<>(); + for (int i = 0; i < localeList.size(); i++) { + systemLocales.add(localeList.get(i)); + } + return systemLocales; } @VisibleForTesting - String[] getAssetSystemLocales() { + String[] getAssetLocales() { try { PackageManager packageManager = mContext.getPackageManager(); return packageManager.getResourcesForApplication( diff --git a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java index ed4c127dcf5..0f9d54b441d 100644 --- a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java +++ b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.LocaleManager; @@ -32,7 +33,7 @@ import androidx.test.annotation.UiThreadTest; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.google.common.collect.Iterables; +import com.android.settingslib.widget.RadioButtonPreference; import org.junit.Before; import org.junit.Test; @@ -40,8 +41,14 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.ArrayList; +import java.util.Collection; import java.util.Locale; +/** + * Unittest for ApplocaleDetails + * TODO Need to add a unittest for the UI preference component. + */ @RunWith(AndroidJUnit4.class) public class AppLocaleDetailsTest { private static final String APP_PACKAGE_NAME = "app_package_name"; @@ -52,7 +59,7 @@ public class AppLocaleDetailsTest { private LocaleManager mLocaleManager; private Context mContext; - private LocaleList mSystemLocales; + private Collection mSystemLocales; private LocaleList mAppLocale; private String[] mAssetLocales; private LocaleList mPackageLocales; @@ -69,12 +76,48 @@ public class AppLocaleDetailsTest { when(mContext.getSystemService(LocaleManager.class)).thenReturn(mLocaleManager); setupInitialLocales( - /* appLocale= */ "en", + /* appLocale= */ "en-gb", /* simCountry= */ "tw", /* networkCountry= */ "jp", - /* systemLocales= */ "en, uk, jp, ne", - /* packageLocales= */ "pa, cn, tw, en", - /* assetLocales= */ new String[]{"en", "ne", "ms", "pa"}); + /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw", + /* packageLocales= */ "pa, cn, zh-tw, en-gb, ja-jp", + /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"}); + } + + @Test + @UiThreadTest + public void onRadioButtonClicked_setCurrentLocaleToSystem() { + AppLocaleDetails appLocaleDetails = new AppLocaleDetails() { + @Override + void refreshUiInternal() {} + }; + DummyAppLocaleDetailsHelper helper = + spy(new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME)); + appLocaleDetails.mAppLocaleDetailsHelper = helper; + RadioButtonPreference pref = new RadioButtonPreference(mContext); + pref.setKey(AppLocaleDetails.KEY_SYSTEM_DEFAULT_LOCALE); + + appLocaleDetails.onRadioButtonClicked(pref); + + verify(helper).setAppDefaultLocale(LocaleList.forLanguageTags("")); + } + + @Test + @UiThreadTest + public void onRadioButtonClicked_setCurrentLocaleForUserSelected() { + AppLocaleDetails appLocaleDetails = new AppLocaleDetails() { + @Override + void refreshUiInternal() {} + }; + DummyAppLocaleDetailsHelper helper = + spy(new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME)); + appLocaleDetails.mAppLocaleDetailsHelper = helper; + RadioButtonPreference pref = new RadioButtonPreference(mContext); + pref.setKey("en"); + + appLocaleDetails.onRadioButtonClicked(pref); + + verify(helper).setAppDefaultLocale("en"); } @Test @@ -90,7 +133,7 @@ public class AppLocaleDetailsTest { @Test @UiThreadTest - public void handleAllLocalesData_1stLocaleOfSuggestedLocaleListIsAppLocale() { + public void handleAllLocalesData_1stLocaleIsAppLocaleAndHasSimAndNetwork() { Locale simCountryLocale = new Locale("zh", "TW"); Locale networkCountryLocale = new Locale("ja", "JP"); DummyAppLocaleDetailsHelper helper = @@ -98,36 +141,122 @@ public class AppLocaleDetailsTest { helper.handleAllLocalesData(); - Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); + Collection suggestedLocales = helper.getSuggestedLocales(); + Locale locale = suggestedLocales.iterator().next(); assertTrue(locale.equals(mAppLocale.get(0))); - assertTrue(helper.getSuggestedLocales().contains(simCountryLocale)); - assertTrue(helper.getSuggestedLocales().contains(networkCountryLocale)); + assertTrue(suggestedLocales.contains(simCountryLocale)); + assertTrue(suggestedLocales.contains(networkCountryLocale)); } @Test @UiThreadTest - public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsSimCountryLocale() { - Locale simCountryLocale = new Locale("zh", "TW"); + public void + handleAllLocalesData_noAppAndNoSupportedSimLocale_1stSuggestedLocaleIsAssetLocale() { + Locale firstAssetLocale = new Locale("en", "GB"); setupInitialLocales( /* appLocale= */ "", /* simCountry= */ "tw", /* networkCountry= */ "", - /* systemLocales= */ "en, uk, jp, ne", + /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw", /* packageLocales= */ "", - /* assetLocales= */ new String[]{}); + /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp"}); DummyAppLocaleDetailsHelper helper = new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); helper.handleAllLocalesData(); - Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); - assertTrue(locale.equals(simCountryLocale)); - assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0))); + Collection suggestedLocales = helper.getSuggestedLocales(); + Locale locale = suggestedLocales.iterator().next(); + assertTrue(locale.equals(firstAssetLocale)); } @Test @UiThreadTest - public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsNetworkCountryLocale() { + public void handleAllLocalesData_noAppButHasSupportedSimLocale_1stSuggestedLocaleIsSim() { + Locale simLocale = new Locale("zh", "tw"); + setupInitialLocales( + /* appLocale= */ "", + /* simCountry= */ "tw", + /* networkCountry= */ "", + /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw", + /* packageLocales= */ "", + /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp", "zh-tw"}); + DummyAppLocaleDetailsHelper helper = + new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); + + helper.handleAllLocalesData(); + + Collection suggestedLocales = helper.getSuggestedLocales(); + Locale locale = suggestedLocales.iterator().next(); + assertTrue(locale.equals(simLocale)); + } + + @Test + @UiThreadTest + public void + handleAllLocalesData_noAppButHasSupportedNetworkLocale_1stSuggestedLocaleIsNetwork() { + Locale networkLocale = new Locale("ja", "JP"); + setupInitialLocales( + /* appLocale= */ "", + /* simCountry= */ "", + /* networkCountry= */ "jp", + /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw", + /* packageLocales= */ "", + /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp"}); + DummyAppLocaleDetailsHelper helper = + new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); + + helper.handleAllLocalesData(); + + Collection suggestedLocales = helper.getSuggestedLocales(); + Locale locale = suggestedLocales.iterator().next(); + assertTrue(locale.equals(networkLocale)); + } + + @Test + @UiThreadTest + public void handleAllLocalesData_noAppSimOrNetworkLocale_suggestedLocalesHasSystemLocale() { + setupInitialLocales( + /* appLocale= */ "", + /* simCountry= */ "", + /* networkCountry= */ "", + /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw", + /* packageLocales= */ "", + /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"}); + DummyAppLocaleDetailsHelper helper = + new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); + helper.handleAllLocalesData(); + + Collection suggestedLocales = helper.getSuggestedLocales(); + assertTrue(suggestedLocales.contains(Locale.forLanguageTag("ne"))); + // ru language is not present in the asset locales + assertFalse(suggestedLocales.contains(Locale.forLanguageTag("ru"))); + } + + @Test + @UiThreadTest + public void handleAllLocalesData_noAppButHasSimAndNetworkLocale_1stLocaleIsSimLocale() { + Locale simCountryLocale = new Locale("zh", "TW"); + setupInitialLocales( + /* appLocale= */ "", + /* simCountry= */ "tw", + /* networkCountry= */ "jp", + /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw", + /* packageLocales= */ "", + /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"}); + + DummyAppLocaleDetailsHelper helper = + new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); + helper.handleAllLocalesData(); + + Collection suggestedLocales = helper.getSuggestedLocales(); + Locale locale = suggestedLocales.iterator().next(); + assertTrue(locale.equals(simCountryLocale)); + } + + @Test + @UiThreadTest + public void handleAllLocalesData_noSupportedLocale_noSuggestedLocales() { Locale networkCountryLocale = new Locale("en", "GB"); setupInitialLocales( /* appLocale= */ "", @@ -141,28 +270,8 @@ public class AppLocaleDetailsTest { helper.handleAllLocalesData(); - Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); - assertTrue(locale.equals(networkCountryLocale)); - assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0))); - } - - @Test - @UiThreadTest - public void handleAllLocalesData_noAppAndSimNetworkLocale_1stLocaleIsFirstOneInSystemLocales() { - setupInitialLocales( - /* appLocale= */ "", - /* simCountry= */ "", - /* networkCountry= */ "", - /* systemLocales= */ "en, uk, jp, ne", - /* packageLocales= */ "", - /* assetLocales= */ new String[]{}); - DummyAppLocaleDetailsHelper helper = - new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); - - helper.handleAllLocalesData(); - - Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); - assertTrue(locale.equals(mSystemLocales.get(0))); + Collection suggestedLocales = helper.getSuggestedLocales(); + assertTrue(suggestedLocales.size() == 0); } @Test @@ -180,8 +289,10 @@ public class AppLocaleDetailsTest { helper.handleAllLocalesData(); - Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); - assertTrue(locale.equals(mSystemLocales.get(0))); + Collection suggestedLocales = helper.getSuggestedLocales(); + Locale locale = suggestedLocales.iterator().next(); + Locale systemLocale = mSystemLocales.iterator().next(); + assertTrue(locale.equals(systemLocale)); } @Test @@ -248,15 +359,23 @@ public class AppLocaleDetailsTest { String packageLocales, String[] assetLocales) { mAppLocale = LocaleList.forLanguageTags(appLocale); - mSystemLocales = LocaleList.forLanguageTags(systemLocales); + // forLanguageTags does not filter space to the input string. If there is any space included + // in string, this will make locale fail to generate. + systemLocales = systemLocales.replaceAll("\\s+", ""); + LocaleList listOfSystemLocales = LocaleList.forLanguageTags(systemLocales); + mSystemLocales = new ArrayList<>(); + for (int i = 0; i < listOfSystemLocales.size(); i++) { + mSystemLocales.add(listOfSystemLocales.get(i)); + } mAssetLocales = assetLocales; + packageLocales = packageLocales.replaceAll("\\s+", ""); mPackageLocales = LocaleList.forLanguageTags(packageLocales); when(mTelephonyManager.getSimCountryIso()).thenReturn(simCountry); when(mTelephonyManager.getNetworkCountryIso()).thenReturn(networkCountry); when(mLocaleManager.getApplicationLocales(anyString())).thenReturn(mAppLocale); } - private class DummyAppLocaleDetailsHelper + public class DummyAppLocaleDetailsHelper extends AppLocaleDetails.AppLocaleDetailsHelper { DummyAppLocaleDetailsHelper(Context context, String packageName) { @@ -264,12 +383,12 @@ public class AppLocaleDetailsTest { } @Override - String[] getAssetSystemLocales() { + String[] getAssetLocales() { return mAssetLocales; } @Override - LocaleList getCurrentSystemLocales() { + Collection getCurrentSystemLocales() { return mSystemLocales; } From 4ca57b3c4ef4b0ae80537cf1b5b3e62af0cf01fb Mon Sep 17 00:00:00 2001 From: tom hsu Date: Mon, 14 Feb 2022 12:39:19 +0800 Subject: [PATCH 15/16] [Panlingual] Remove Icon of system language Bug: 219384592 Test: local Change-Id: Ib28461752150a66ab0edd0a3c2d631a6d600075c --- res/xml/language_and_input.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml index c99d5911686..770a862f3d1 100644 --- a/res/xml/language_and_input.xml +++ b/res/xml/language_and_input.xml @@ -25,7 +25,6 @@ Date: Mon, 14 Feb 2022 15:59:55 +0000 Subject: [PATCH 16/16] Log clicks on the "Show System / Hide System" button in Location Settings recent accesses. Bug: 191503437 Test: manual Change-Id: I2bcae63832c0a38a95f8087e2a4b5cf625ee7604 --- .../RecentLocationAccessSeeAllPreferenceController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java index e3379c7da7f..75406f7132a 100644 --- a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java +++ b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java @@ -27,7 +27,9 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; +import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.applications.RecentAppOpsAccess; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.widget.AppPreference; import java.util.ArrayList; @@ -37,8 +39,10 @@ import java.util.List; public class RecentLocationAccessSeeAllPreferenceController extends LocationBasePreferenceController { - private PreferenceScreen mCategoryAllRecentLocationAccess; private final RecentAppOpsAccess mRecentLocationAccesses; + + private PreferenceScreen mCategoryAllRecentLocationAccess; + private MetricsFeatureProvider mMetricsFeatureProvider; private boolean mShowSystem = false; private Preference mPreference; @@ -47,6 +51,7 @@ public class RecentLocationAccessSeeAllPreferenceController mShowSystem = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1; mRecentLocationAccesses = RecentAppOpsAccess.createForLocation(context); + mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } @Override @@ -99,6 +104,7 @@ public class RecentLocationAccessSeeAllPreferenceController mShowSystem = showSystem; if (mPreference != null) { updateState(mPreference); + mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory()); } } }