From b71de640b56abb4669cee12b32b2700d39b52d5a Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Tue, 2 Aug 2022 13:04:24 +0000 Subject: [PATCH 01/13] Add a new NFC developer setting option for NFCSNOOP Add a new developer setting option to enable full NFCSNOOP log. Bug: 204397062 Test: manual Change-Id: I3fd34500e5e7093c9d77ff737987a35f6866814e --- res/values/strings.xml | 11 ++ res/xml/development_settings.xml | 5 + .../DevelopmentSettingsDashboardFragment.java | 18 ++- .../settings/development/NfcRebootDialog.java | 99 ++++++++++++++ .../NfcSnoopLogPreferenceController.java | 129 ++++++++++++++++++ 5 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 src/com/android/settings/development/NfcRebootDialog.java create mode 100644 src/com/android/settings/development/NfcSnoopLogPreferenceController.java diff --git a/res/values/strings.xml b/res/values/strings.xml index cc7690e2c1e..a6d8eeb17f1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1962,6 +1962,17 @@ Increase NFC stack logging level + + NFC NCI unfiltered snoop log + + Capture detail NFC packets, which may contain private information. + + Restart Device? + + Detail NFC logging is intended for development purposes only. Additional NFC data is included in bug reports, which may contain private information. Restart your device to change this setting. + + Restart + Cast diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 19c12091400..3cccf01700a 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -402,6 +402,11 @@ android:title="@string/nfc_stack_debuglog_title" android:summary="@string/nfc_stack_debuglog_summary" /> + + Date: Tue, 2 Aug 2022 13:31:59 +0000 Subject: [PATCH 02/13] Add a new NFC developer setting option for NFC vendor verbose log Add a new developer setting option to enable vendor verbose log. Bug: 204397062 Test: manual Change-Id: Ic837bbcc32979c44732e99d51e4dcf93eb201cf1 --- res/values/strings.xml | 4 + res/xml/development_settings.xml | 5 + .../DevelopmentSettingsDashboardFragment.java | 9 ++ ...cVerboseVendorLogPreferenceController.java | 130 ++++++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 src/com/android/settings/development/NfcVerboseVendorLogPreferenceController.java diff --git a/res/values/strings.xml b/res/values/strings.xml index a6d8eeb17f1..bb98ad0d796 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1962,6 +1962,10 @@ Increase NFC stack logging level + + NFC verbose vendor debug log + + Include additional device-specific vendor logs in bugreports, which may contain private information. NFC NCI unfiltered snoop log diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 3cccf01700a..a0640f5be70 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -402,6 +402,11 @@ android:title="@string/nfc_stack_debuglog_title" android:summary="@string/nfc_stack_debuglog_summary" /> + + Date: Thu, 4 Aug 2022 09:52:30 +0000 Subject: [PATCH 03/13] Show reboot dialog when users disable developer options When NFC detailed logging mechanisms are enabled and users try to disable develoepr options, show reboot request dialog to make sure NFC logging mechanisms are also disabled. Bug: 204397062 Test: manual Change-Id: I531c85fd77934ad7821c480df07465a8cd8f24f9 --- .../DevelopmentSettingsDashboardFragment.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 856bee37e26..210d0115334 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -300,10 +300,19 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra final BluetoothLeAudioHwOffloadPreferenceController leAudioController = getDevelopmentOptionsController( BluetoothLeAudioHwOffloadPreferenceController.class); + final NfcSnoopLogPreferenceController nfcSnoopLogController = + getDevelopmentOptionsController( + NfcSnoopLogPreferenceController.class); + final NfcVerboseVendorLogPreferenceController nfcVerboseLogController = + getDevelopmentOptionsController( + NfcVerboseVendorLogPreferenceController.class); // If hardware offload isn't default value, we must reboot after disable // developer options. Show a dialog for the user to confirm. if ((a2dpController == null || a2dpController.isDefaultValue()) - && (leAudioController == null || leAudioController.isDefaultValue())) { + && (leAudioController == null || leAudioController.isDefaultValue()) + && (nfcSnoopLogController == null || nfcSnoopLogController.isDefaultValue()) + && (nfcVerboseLogController == null + || nfcVerboseLogController.isDefaultValue())) { disableDeveloperOptions(); } else { DisableDevSettingsDialogFragment.show(this /* host */); From bcf2efe31e5f9e9bd131b2db83b2a6b379e255a4 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Thu, 18 Aug 2022 13:11:11 +0000 Subject: [PATCH 04/13] Add test cases for NfcSnoopLog and NfcVerboseVendorLog Bug: 204397062 Test: make RunSettingsRoboTests Change-Id: Id12e3c10dc04816d4a69692b2d922840a8e84c61 --- .../NfcSnoopLogPreferenceControllerTest.java | 99 +++++++++++++++++++ ...boseVendorLogPreferenceControllerTest.java | 99 +++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 tests/robotests/src/com/android/settings/development/NfcSnoopLogPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/development/NfcVerboseVendorLogPreferenceControllerTest.java diff --git a/tests/robotests/src/com/android/settings/development/NfcSnoopLogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/NfcSnoopLogPreferenceControllerTest.java new file mode 100644 index 00000000000..4ea5475f02a --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/NfcSnoopLogPreferenceControllerTest.java @@ -0,0 +1,99 @@ +/* + * 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.development; + +import static com.android.settings.development.NfcSnoopLogPreferenceController + .NFCSNOOP_MODE_FILTERED; +import static com.android.settings.development.NfcSnoopLogPreferenceController + .NFCSNOOP_MODE_FULL; +import static com.android.settings.development.NfcSnoopLogPreferenceController + .NFC_NFCSNOOP_LOG_MODE_PROPERTY; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.SystemProperties; + +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class NfcSnoopLogPreferenceControllerTest { + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private DevelopmentSettingsDashboardFragment mFragment; + + private Context mContext; + private SwitchPreference mPreference; + private NfcSnoopLogPreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mPreference = new SwitchPreference(mContext); + mController = spy(new NfcSnoopLogPreferenceController(mContext, mFragment)); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mPreference); + mController.displayPreference(mPreferenceScreen); + } + + @Test + public void onNfcRebootDialogConfirmed_nfcSnoopLogDisabled_shouldChangeProperty() { + SystemProperties.set(NFC_NFCSNOOP_LOG_MODE_PROPERTY, NFCSNOOP_MODE_FILTERED); + mController.mChanged = true; + + mController.onNfcRebootDialogConfirmed(); + + final String currentValue = SystemProperties.get(NFC_NFCSNOOP_LOG_MODE_PROPERTY); + assertThat(currentValue.equals(NFCSNOOP_MODE_FULL)).isTrue(); + } + + @Test + public void onNfcRebootDialogConfirmed_nfcSnoopLogEnabled_shouldChangeProperty() { + SystemProperties.set(NFC_NFCSNOOP_LOG_MODE_PROPERTY, NFCSNOOP_MODE_FULL); + mController.mChanged = true; + + mController.onNfcRebootDialogConfirmed(); + + final String currentValue = SystemProperties.get(NFC_NFCSNOOP_LOG_MODE_PROPERTY); + assertThat(currentValue.equals(NFCSNOOP_MODE_FILTERED)).isTrue(); + } + + @Test + public void onNfcRebootDialogCanceled_shouldNotChangeProperty() { + SystemProperties.set(NFC_NFCSNOOP_LOG_MODE_PROPERTY, NFCSNOOP_MODE_FILTERED); + mController.mChanged = true; + + mController.onNfcRebootDialogCanceled(); + + final String currentValue = SystemProperties.get(NFC_NFCSNOOP_LOG_MODE_PROPERTY); + assertThat(currentValue.equals(NFCSNOOP_MODE_FILTERED)).isTrue(); + } +} diff --git a/tests/robotests/src/com/android/settings/development/NfcVerboseVendorLogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/NfcVerboseVendorLogPreferenceControllerTest.java new file mode 100644 index 00000000000..49ddd30dc35 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/NfcVerboseVendorLogPreferenceControllerTest.java @@ -0,0 +1,99 @@ +/* + * 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.development; + +import static com.android.settings.development.NfcVerboseVendorLogPreferenceController + .NFC_VERBOSE_VENDOR_LOG_PROPERTY; +import static com.android.settings.development.NfcVerboseVendorLogPreferenceController + .VERBOSE_VENDOR_LOG_DISABLED; +import static com.android.settings.development.NfcVerboseVendorLogPreferenceController + .VERBOSE_VENDOR_LOG_ENABLED; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.SystemProperties; + +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class NfcVerboseVendorLogPreferenceControllerTest { + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private DevelopmentSettingsDashboardFragment mFragment; + + private Context mContext; + private SwitchPreference mPreference; + private NfcVerboseVendorLogPreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mPreference = new SwitchPreference(mContext); + mController = spy(new NfcVerboseVendorLogPreferenceController(mContext, mFragment)); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mPreference); + mController.displayPreference(mPreferenceScreen); + } + + @Test + public void onNfcRebootDialogConfirmed_nfcVendorLogDisabled_shouldChangeProperty() { + SystemProperties.set(NFC_VERBOSE_VENDOR_LOG_PROPERTY, VERBOSE_VENDOR_LOG_DISABLED); + mController.mChanged = true; + + mController.onNfcRebootDialogConfirmed(); + + final String currentValue = SystemProperties.get(NFC_VERBOSE_VENDOR_LOG_PROPERTY); + assertThat(currentValue.equals(VERBOSE_VENDOR_LOG_ENABLED)).isTrue(); + } + + @Test + public void onNfcRebootDialogConfirmed_nfcVendorLogEnabled_shouldChangeProperty() { + SystemProperties.set(NFC_VERBOSE_VENDOR_LOG_PROPERTY, VERBOSE_VENDOR_LOG_ENABLED); + mController.mChanged = true; + + mController.onNfcRebootDialogConfirmed(); + + final String currentValue = SystemProperties.get(NFC_VERBOSE_VENDOR_LOG_PROPERTY); + assertThat(currentValue.equals(VERBOSE_VENDOR_LOG_DISABLED)).isTrue(); + } + + @Test + public void onNfcRebootDialogCanceled_shouldNotChangeProperty() { + SystemProperties.set(NFC_VERBOSE_VENDOR_LOG_PROPERTY, VERBOSE_VENDOR_LOG_DISABLED); + mController.mChanged = true; + + mController.onNfcRebootDialogCanceled(); + + final String currentValue = SystemProperties.get(NFC_VERBOSE_VENDOR_LOG_PROPERTY); + assertThat(currentValue.equals(VERBOSE_VENDOR_LOG_DISABLED)).isTrue(); + } +} From 3cbb6f86802ade7aac51234a070b6f623d829081 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Thu, 11 Aug 2022 23:51:24 +0800 Subject: [PATCH 05/13] [Languages] Add new information to system language page. - Add top Intro preference - Add footer preference - Add sub string to language picker - Modify title of app locale pages Bug: 242182598 Add information to system language page. Bug: 241600418 [Panlingual] Change strings on App languages Test: Maunal test Change-Id: I9bca8911e8e70c97c273294b3c9d1d73d4ea0cb2 --- res/layout/locale_drag_cell.xml | 11 +++ res/values/strings.xml | 24 +++++- res/xml/languages.xml | 42 +++++++++++ .../LocaleDragAndDropAdapter.java | 3 +- .../settings/localepicker/LocaleDragCell.java | 10 +++ .../LocaleHelperPreferenceController.java | 74 +++++++++++++++++++ .../localepicker/LocaleListEditor.java | 27 +++++-- .../LocaleHelperPreferenceControllerTest.java | 59 +++++++++++++++ 8 files changed, 238 insertions(+), 12 deletions(-) create mode 100644 res/xml/languages.xml create mode 100644 src/com/android/settings/localepicker/LocaleHelperPreferenceController.java create mode 100644 tests/unit/src/com/android/settings/localepicker/LocaleHelperPreferenceControllerTest.java 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 @@ -497,13 +503,13 @@ Preferred Language - App Languages + App languages Set the language for each app - App Language + App language Suggested languages @@ -526,6 +532,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? @@ -541,7 +559,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/languages.xml b/res/xml/languages.xml new file mode 100644 index 00000000000..0f455407645 --- /dev/null +++ b/res/xml/languages.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + 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/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()); + } +} From e6b46dc853877d07597e7fb144b12cd8940a1b26 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Fri, 19 Aug 2022 15:54:53 +0800 Subject: [PATCH 06/13] [Panlingual] Remove featureflag of app language. Panlingual successfully landed. Hence, we can remove the feature flag right now. Bug: b/209775925 Test: atest pass Test: Manual test pass Change-Id: I464a206027fd63ee1763acaf17d1b6251e839bc0 --- .../AppLocalePreferenceController.java | 5 +- .../ManageAppLocalePreferenceController.java | 40 ----------- .../AppLocalePreferenceControllerTest.java | 27 +------- ...nageAppLocalePreferenceControllerTest.java | 66 ------------------- 4 files changed, 3 insertions(+), 135 deletions(-) delete mode 100644 src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceController.java delete mode 100644 tests/unit/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceControllerTest.java 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/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); - } -} From 3aa4440b364da62627fd5677848e2d26b8b3c9d1 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Fri, 19 Aug 2022 15:12:50 +0800 Subject: [PATCH 07/13] [Panlingual] Improve conditions of supporting app locale. There are 3 conditions we need to check. 1. Has locale config file 2. Has locale config file w/o content 3. Has locale config file w/ content Currently, we do not have condition 2 into the condition group, and we need to add it into. Bug: b/243099750 Test: Manual Change-Id: I58d0275af53031ba4f4c705022017d5143f45795 --- src/com/android/settings/applications/AppLocaleUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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( From 5a87f6bbbfb2cb21f2f9e398d5e6fae7f756b3f5 Mon Sep 17 00:00:00 2001 From: menghanli Date: Wed, 24 Aug 2022 19:35:38 +0800 Subject: [PATCH 08/13] Fix tapping magnification crash in vision settings setup screen Root cause: ag/17286343 introduces hiding the settings entry in magnification settings if window magnification feature is not supported. It causes SuW page cannot find the settings preference reference. Solution: Add null pointer check. Bug: 242242266 Test: Manual testing Change-Id: I1007a580047dd302228b28c15b82e958a2b01fec --- ...agnificationPreferenceFragmentForSetupWizard.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java index cb5ca759df1..12a988603d8 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java @@ -52,11 +52,17 @@ public class ToggleScreenMagnificationPreferenceFragmentForSetupWizard */ private void hidePreferenceSettingComponents() { // Intro - mTopIntroPreference.setVisible(false); + if (mTopIntroPreference != null) { + mTopIntroPreference.setVisible(false); + } // Setting of magnification type - mSettingsPreference.setVisible(false); + if (mSettingsPreference != null) { + mSettingsPreference.setVisible(false); + } // Setting of following typing - mFollowingTypingSwitchPreference.setVisible(false); + if (mFollowingTypingSwitchPreference != null) { + mFollowingTypingSwitchPreference.setVisible(false); + } } @Override From 7a4ddb83377fa04caaa6c660a849f99c4814dee4 Mon Sep 17 00:00:00 2001 From: lbill Date: Wed, 24 Aug 2022 13:37:11 +0000 Subject: [PATCH 09/13] Set appropriate theme for SkipFingerprintDialog The SkipFingerprintDialog is instantiation in SetupFingerprintEnrollFindSensor#onSkipButtonClick() Due to the call flow did not set appropriate theme defined in setuplib for skip alertDialog instance we set GlifV2ThemeAlertDialog AlertDialog.Builder. Test: m RunSettingsRoboTests -j30 ROBOTEST_FILTER= \ SetupFingerprintEnrollFindSensorTest Test: manual factory reset, go through SUW, and check skip AlertDialog Bottom Bar Buttons visual. Bug: 233243999 Change-Id: Ic198a23eb3e76d70e287b24f2ab1ef249b30b2fc --- .../SetupFingerprintEnrollFindSensor.java | 2 +- .../SetupFingerprintEnrollFindSensorTest.java | 23 +++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) 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/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; } } From 54c677a83c2488d577a047199234d4a152a73acf Mon Sep 17 00:00:00 2001 From: Chloris Kuo Date: Tue, 16 Aug 2022 15:08:29 -0700 Subject: [PATCH 10/13] Support ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS in Enhanced Notifications Show detail settings page from the default NAS app if it implements the new intent ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS. Test: Robotest, manually test on device Bug: 231492005 Change-Id: I6566cd9d615331a56728613583295637982bcd3f Merged-In: I6566cd9d615331a56728613583295637982bcd3f --- res/xml/configure_notification_settings.xml | 2 +- ...ficationAssistantPreferenceController.java | 56 +++++++++++++- ...tionAssistantPreferenceControllerTest.java | 74 ++++++++++++++++++- 3 files changed, 125 insertions(+), 7 deletions(-) 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"/> - 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/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 { From 15a1adbe8f14ab6e60a0e5c6837842788bf0b2d7 Mon Sep 17 00:00:00 2001 From: Joshua McCloskey Date: Wed, 20 Jul 2022 01:47:37 +0000 Subject: [PATCH 11/13] Replaced fingerprint finish strings. Test: Verified manually correct string shows. Fixes: 239614495 Change-Id: I5b52d21fb6a9faf5769de46ccb17308a1649e22a --- res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 921cb5227fe..18570a8d590 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1184,11 +1184,11 @@ Fingerprint added - Fingerprint Unlock improves the more you use it to unlock your tablet or verify it\u2019s you in apps + Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps - Fingerprint Unlock improves the more you use it to unlock your device or verify it\u2019s you in apps + Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps - Fingerprint Unlock improves the more you use it to unlock your phone or verify it\u2019s you in apps + Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps Do it later From 079aaf1261f25769e664625869205a7e3841ed82 Mon Sep 17 00:00:00 2001 From: Zaiyue Xue Date: Thu, 25 Aug 2022 13:41:24 +0800 Subject: [PATCH 12/13] Fix b/243746796 Crash when mouse hangs over an empty battery chart Bug: 243746796 Fix: 243746796 Test: manual Change-Id: I3e595c96a55f1114b50ed5ed8e49e962cc90cbde --- .../fuelgauge/batteryusage/BatteryChartView.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java index e668b37c24e..1a009eaa436 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java @@ -595,11 +595,13 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick // Searches the corresponding trapezoid index from x location. private int getTrapezoidIndex(float x) { - for (int index = 0; index < mTrapezoidSlots.length; index++) { - final TrapezoidSlot slot = mTrapezoidSlots[index]; - if (x >= slot.mLeft - mTrapezoidHOffset - && x <= slot.mRight + mTrapezoidHOffset) { - return index; + if (mTrapezoidSlots != null) { + for (int index = 0; index < mTrapezoidSlots.length; index++) { + final TrapezoidSlot slot = mTrapezoidSlots[index]; + if (x >= slot.mLeft - mTrapezoidHOffset + && x <= slot.mRight + mTrapezoidHOffset) { + return index; + } } } return BatteryChartViewModel.SELECTED_INDEX_INVALID; From 8e00605228a891780aa0b9e365671a8261760c99 Mon Sep 17 00:00:00 2001 From: Zaiyue Xue Date: Thu, 25 Aug 2022 14:50:32 +0800 Subject: [PATCH 13/13] Fix b/243485315: NullPointerException when getAppBatteryUsageData(). Bug: 243485315 Fix: 243485315 Test: presubmit Change-Id: I8bb2db7976f6c8817e9ab45fe3a40456afcd8128 --- .../BatteryChartPreferenceController.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java index 45ae8c595bf..f3fec8e1973 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java @@ -697,12 +697,13 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll final Map> batteryUsageData = DataProcessor.getBatteryUsageData(context, batteryHistoryMap); - return batteryUsageData == null - ? null - : batteryUsageData - .get(BatteryChartViewModel.SELECTED_INDEX_ALL) - .get(BatteryChartViewModel.SELECTED_INDEX_ALL) - .getAppDiffEntryList(); + if (batteryUsageData == null) { + return null; + } + BatteryDiffData allBatteryDiffData = batteryUsageData.get( + BatteryChartViewModel.SELECTED_INDEX_ALL).get( + BatteryChartViewModel.SELECTED_INDEX_ALL); + return allBatteryDiffData == null ? null : allBatteryDiffData.getAppDiffEntryList(); } /** Used for {@link AppBatteryPreferenceController}. */