diff --git a/res/drawable/ic_fast_pair_24dp.xml b/res/drawable/ic_fast_pair_24dp.xml new file mode 100644 index 00000000000..17bfdd9143f --- /dev/null +++ b/res/drawable/ic_fast_pair_24dp.xml @@ -0,0 +1,36 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/layout/accessibility_launch_activity_preference.xml b/res/layout/accessibility_launch_activity_preference.xml index 0e3e2251d44..26a1c334212 100644 --- a/res/layout/accessibility_launch_activity_preference.xml +++ b/res/layout/accessibility_launch_activity_preference.xml @@ -34,5 +34,6 @@ android:ellipsize="end" android:textAppearance="?android:attr/textAppearanceListItem" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" style="@style/MainSwitchText.Settingslib" /> diff --git a/res/layout/accessibility_shortcut_secondary_action.xml b/res/layout/accessibility_shortcut_secondary_action.xml index ddbadb5b911..b3b81fe5593 100644 --- a/res/layout/accessibility_shortcut_secondary_action.xml +++ b/res/layout/accessibility_shortcut_secondary_action.xml @@ -60,6 +60,7 @@ android:singleLine="true" android:textAppearance="?android:attr/textAppearanceListItem" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:ellipsize="marquee" /> diff --git a/res/layout/accessibility_text_reading_preview.xml b/res/layout/accessibility_text_reading_preview.xml index 9caed300594..91fb0a00486 100644 --- a/res/layout/accessibility_text_reading_preview.xml +++ b/res/layout/accessibility_text_reading_preview.xml @@ -18,6 +18,7 @@ diff --git a/res/layout/apn_preference_layout.xml b/res/layout/apn_preference_layout.xml index 2c453aa591e..241be74fe29 100644 --- a/res/layout/apn_preference_layout.xml +++ b/res/layout/apn_preference_layout.xml @@ -52,6 +52,7 @@ android:textColor="?android:attr/textColorSecondary" android:focusable="false" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:maxLines="2" /> diff --git a/res/layout/app_preference_item.xml b/res/layout/app_preference_item.xml index c6857604c79..7e7ff392bd6 100755 --- a/res/layout/app_preference_item.xml +++ b/res/layout/app_preference_item.xml @@ -57,6 +57,7 @@ android:ellipsize="marquee" android:duplicateParentState="true" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" /> + + + + + diff --git a/res/layout/horizontal_preference.xml b/res/layout/horizontal_preference.xml index d87963cc446..922143b4df2 100644 --- a/res/layout/horizontal_preference.xml +++ b/res/layout/horizontal_preference.xml @@ -31,6 +31,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:layout_weight="1" /> diff --git a/res/layout/notification_app.xml b/res/layout/notification_app.xml index 2d17c8d9b15..15e83f1837b 100644 --- a/res/layout/notification_app.xml +++ b/res/layout/notification_app.xml @@ -39,6 +39,7 @@ android:singleLine="true" android:textAlignment="viewStart" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:textAppearance="?android:attr/textAppearanceMedium" /> diff --git a/res/layout/preference_balance_slider.xml b/res/layout/preference_balance_slider.xml index 3f1c4edfb9d..278cf793d43 100644 --- a/res/layout/preference_balance_slider.xml +++ b/res/layout/preference_balance_slider.xml @@ -46,6 +46,7 @@ android:textColor="?android:attr/textColorPrimary" android:ellipsize="marquee" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:fadingEdge="horizontal"/> diff --git a/res/layout/preference_labeled_slider.xml b/res/layout/preference_labeled_slider.xml index 610b79f1e13..ae7027defe8 100644 --- a/res/layout/preference_labeled_slider.xml +++ b/res/layout/preference_labeled_slider.xml @@ -36,6 +36,7 @@ android:singleLine="true" android:textAppearance="?android:attr/textAppearanceListItem" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:textColor="?android:attr/textColorPrimary" /> @@ -75,6 +79,8 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="end|top" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary" android:gravity="end" android:layout_weight="1"/> diff --git a/res/layout/preference_multiline_title.xml b/res/layout/preference_multiline_title.xml index d68e8c1a930..9612a577835 100644 --- a/res/layout/preference_multiline_title.xml +++ b/res/layout/preference_multiline_title.xml @@ -39,6 +39,7 @@ android:textAlignment="center" android:ellipsize="marquee" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:fadingEdge="horizontal" /> diff --git a/res/layout/preference_progress_category.xml b/res/layout/preference_progress_category.xml index 9e33c5d4476..b04f5bee659 100644 --- a/res/layout/preference_progress_category.xml +++ b/res/layout/preference_progress_category.xml @@ -48,6 +48,7 @@ android:layout_gravity="start|center" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:textColor="?android:attr/colorAccent"/> diff --git a/res/layout/preference_two_target_radio.xml b/res/layout/preference_two_target_radio.xml index e5e6d4a3a00..ece07464f52 100644 --- a/res/layout/preference_two_target_radio.xml +++ b/res/layout/preference_two_target_radio.xml @@ -74,6 +74,7 @@ android:textAppearance="?android:attr/textAppearanceListItemSecondary" android:textColor="?android:attr/textColorSecondary" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:maxLines="10" /> diff --git a/res/layout/radio_with_summary.xml b/res/layout/radio_with_summary.xml index 2f39e6746c9..ac65a0e81e4 100644 --- a/res/layout/radio_with_summary.xml +++ b/res/layout/radio_with_summary.xml @@ -34,6 +34,7 @@ android:paddingStart="20dp" android:drawableStart="?android:attr/listChoiceIndicatorSingle" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:ellipsize="marquee" /> @@ -45,6 +46,7 @@ android:textAppearance="?android:attr/textAppearanceListItemSecondary" android:textColor="?android:attr/textColorSecondary" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:maxLines="10" /> diff --git a/res/layout/running_services_app_item.xml b/res/layout/running_services_app_item.xml index f2585303aea..65328bab338 100644 --- a/res/layout/running_services_app_item.xml +++ b/res/layout/running_services_app_item.xml @@ -56,6 +56,7 @@ android:fadingEdge="horizontal" android:maxLines="2" android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase" android:textAppearance="?android:attr/textAppearanceListItem"/> diff --git a/res/layout/settings_summary_preference.xml b/res/layout/settings_summary_preference.xml index 2f899e170f9..894a5e54661 100644 --- a/res/layout/settings_summary_preference.xml +++ b/res/layout/settings_summary_preference.xml @@ -33,7 +33,8 @@ android:textColor="?android:attr/textColorPrimary" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1" android:hyphenationFrequency="normalFast" - /> + android:lineBreakWordStyle="phrase" + /> diff --git a/res/values/strings.xml b/res/values/strings.xml index 28055ab297a..667ed2825e2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -869,17 +869,10 @@ Fingerprint - Fingerprint for work - - Manage fingerprints - - Use fingerprint for Add fingerprint - - screen lock Fingerprint added @@ -907,12 +900,6 @@ You and your child are in control Keep in mind - - The data recorded by Fingerprint is stored securely and never leaves your phone. You can delete your data anytime in Settings. - - Your fingerprint may be less secure than a strong pattern or PIN. - - Your phone will occasionally use your recent fingerprint images to create improved fingerprint models. Use your fingerprint to unlock your phone or approve purchases.\n\nNote: You can\u2019t use your fingerprint to unlock this device. For more information, contact your organization\u2019s admin. @@ -927,12 +914,6 @@ Fingerprint setup only takes a minute or two. If you skip this, you can add your fingerprint later in settings. - - When you see this icon, use your fingerprint for authentication, like when you sign in to apps or approve a purchase - - Keep in mind - - Using your fingerprint to unlock your phone may be less secure than a strong pattern or PIN How it works @@ -962,21 +943,6 @@ - - Change the position of your finger slightly each time - - Cover the icon with the center of your fingerprint - - This fingerprint has already been added - - Clean your screen near the sensor and try again - - Lift your finger after you feel a vibration - - Move somewhere with gentler lighting and try again - - You\u2019ve reached the maximum number of attempts - Use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps @@ -1223,8 +1189,6 @@ Add another Next - - In addition to unlocking your phone, you can also use your fingerprint to authorize purchases and app access. Learn more The screen lock option is disabled. To learn more, contact your organization\u2019s admin. @@ -5938,6 +5902,19 @@ + + + + + Fast Pair + + + Nearby detection of Fast Pair bluetooth devices. + + Scan for nearby devices + + Saved devices + @@ -6438,8 +6415,12 @@ Battery level for past 24 hr + + App usage since last full charge App usage for past 24 hr + + System usage since last full charge System usage for past 24 hr @@ -8124,6 +8105,9 @@ connected, device, headphones, headset, speaker, wireless, pair, earbuds, music, media + + pair, earbuds, bluetooth + background, theme, grid, customize, personalize diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml index 152446c38c7..e7d178c61f8 100644 --- a/res/xml/connected_devices_advanced.xml +++ b/res/xml/connected_devices_advanced.xml @@ -67,6 +67,15 @@ android:summary="@string/summary_placeholder" settings:controller="com.android.settings.uwb.UwbPreferenceController"/> + + diff --git a/res/xml/fast_pair_settings.xml b/res/xml/fast_pair_settings.xml new file mode 100644 index 00000000000..95662fc47ed --- /dev/null +++ b/res/xml/fast_pair_settings.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/src/com/android/settings/biometrics/BiometricEnrollBase.java b/src/com/android/settings/biometrics/BiometricEnrollBase.java index 75e409825ea..eea1bad91a9 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollBase.java +++ b/src/com/android/settings/biometrics/BiometricEnrollBase.java @@ -181,6 +181,16 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity { getWindow().setStatusBarColor(getBackgroundColor()); } + @Override + protected void onStop() { + super.onStop(); + if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() + && !BiometricUtils.isAnyMultiBiometricFlow(this)) { + setResult(RESULT_TIMEOUT); + finish(); + } + } + protected boolean shouldFinishWhenBackgrounded() { return !WizardManagerHelper.isAnySetupWizard(getIntent()); } diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java index d9f8bd1bf0d..acfe5a10255 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java @@ -241,16 +241,6 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase } } - @Override - protected void onStop() { - if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() - && !BiometricUtils.isAnyMultiBiometricFlow(this)) { - setResult(RESULT_TIMEOUT); - finish(); - } - super.onStop(); - } - @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); diff --git a/src/com/android/settings/biometrics/BiometricHandoffActivity.java b/src/com/android/settings/biometrics/BiometricHandoffActivity.java index 2b8d89b0dfe..7f28ced2029 100644 --- a/src/com/android/settings/biometrics/BiometricHandoffActivity.java +++ b/src/com/android/settings/biometrics/BiometricHandoffActivity.java @@ -49,16 +49,6 @@ public class BiometricHandoffActivity extends BiometricEnrollBase { mFooterBarMixin.setPrimaryButton(getPrimaryFooterButton()); } - @Override - protected void onStop() { - if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() - && !BiometricUtils.isAnyMultiBiometricFlow(this)) { - setResult(RESULT_TIMEOUT); - finish(); - } - super.onStop(); - } - @NonNull protected FooterButton getPrimaryFooterButton() { if (mPrimaryFooterButton == null) { diff --git a/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java b/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java index 6f68f51e911..3a61d5e2243 100644 --- a/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java @@ -62,11 +62,7 @@ public abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase @Override protected void onStop() { - if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() - && !BiometricUtils.isAnyMultiBiometricFlow(this)) { - setResult(RESULT_TIMEOUT); - finish(); - } + super.onStop(); if (mSidecar != null) { mSidecar.setListener(null); @@ -84,7 +80,6 @@ public abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase } finish(); } - super.onStop(); } @Override diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java index cdd99a228a7..d2d356b1104 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java @@ -170,16 +170,6 @@ public class FaceEnrollEducation extends BiometricEnrollBase { } } - @Override - protected void onStop() { - if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() - && !BiometricUtils.isAnyMultiBiometricFlow(this)) { - setResult(RESULT_TIMEOUT); - finish(); - } - super.onStop(); - } - @Override protected boolean shouldFinishWhenBackgrounded() { return super.shouldFinishWhenBackgrounded() && !mNextClicked; diff --git a/src/com/android/settings/biometrics/face/FaceEnrollFinish.java b/src/com/android/settings/biometrics/face/FaceEnrollFinish.java index 135179475dc..6e99cdb344a 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollFinish.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollFinish.java @@ -22,7 +22,6 @@ import android.view.View; import com.android.settings.R; import com.android.settings.biometrics.BiometricEnrollBase; -import com.android.settings.biometrics.BiometricUtils; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; @@ -49,16 +48,6 @@ public class FaceEnrollFinish extends BiometricEnrollBase { ); } - @Override - protected void onStop() { - if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() - && !BiometricUtils.isAnyMultiBiometricFlow(this)) { - setResult(RESULT_TIMEOUT); - finish(); - } - super.onStop(); - } - @Override public int getMetricsCategory() { return SettingsEnums.FACE_ENROLL_FINISHED; diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java index 79a106559ad..627a5143a38 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java @@ -249,15 +249,10 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements @Override protected void onStop() { + super.onStop(); if (mAnimation != null) { mAnimation.pauseAnimation(); } - if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() - && !BiometricUtils.isAnyMultiBiometricFlow(this)) { - setResult(RESULT_TIMEOUT); - finish(); - } - super.onStop(); } @Override diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java index 05ca39c144a..16773d3cbda 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java @@ -108,16 +108,6 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase { } } - @Override - protected void onStop() { - if (!isChangingConfigurations() && shouldFinishWhenBackgrounded() - && !BiometricUtils.isAnyMultiBiometricFlow(this)) { - setResult(RESULT_TIMEOUT); - finish(); - } - super.onStop(); - } - @Override protected void onNextButtonClick(View view) { updateFingerprintSuggestionEnableState(); diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java index 9c24a238051..5f15093259f 100644 --- a/src/com/android/settings/core/SettingsBaseActivity.java +++ b/src/com/android/settings/core/SettingsBaseActivity.java @@ -23,6 +23,7 @@ import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.TypedArray; +import android.graphics.text.LineBreakConfig; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; @@ -109,6 +110,12 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa if (mCollapsingToolbarLayout != null) { mCollapsingToolbarLayout.setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER); mCollapsingToolbarLayout.setHyphenationFrequency(HYPHENATION_FREQUENCY_NORMAL_FAST); + mCollapsingToolbarLayout.setStaticLayoutBuilderConfigurer(builder -> + builder.setLineBreakConfig( + new LineBreakConfig.Builder() + .setLineBreakWordStyle( + LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE) + .build())); } disableCollapsingToolbarLayoutScrollingBehavior(); } else { diff --git a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java index 62bcffbfc28..c9cc2b79beb 100644 --- a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java +++ b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java @@ -40,7 +40,11 @@ public abstract class AbstractBluetoothDialogPreferenceController extends private static final String TAG = "AbstractBtDlgCtr"; - protected static final int[] CODEC_TYPES = {BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO(b/240635097): remove in U + + protected static final int[] CODEC_TYPES = {SOURCE_CODEC_TYPE_OPUS, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreference.java b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreference.java index 6a733f3fbab..929a6d02f10 100644 --- a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreference.java +++ b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreference.java @@ -61,6 +61,8 @@ public class BluetoothCodecDialogPreference extends BaseBluetoothDialogPreferenc mRadioButtonIds.add(R.id.bluetooth_audio_codec_aptx); mRadioButtonIds.add(R.id.bluetooth_audio_codec_aptx_hd); mRadioButtonIds.add(R.id.bluetooth_audio_codec_ldac); + mRadioButtonIds.add(R.id.bluetooth_audio_codec_lc3); + mRadioButtonIds.add(R.id.bluetooth_audio_codec_opus); String[] stringArray = context.getResources().getStringArray( R.array.bluetooth_a2dp_codec_titles); for (int i = 0; i < stringArray.length; i++) { diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java index a65a1ba8cd4..87d5ff09fc5 100644 --- a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java +++ b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java @@ -40,6 +40,8 @@ public class BluetoothCodecDialogPreferenceController extends private static final String KEY = "bluetooth_audio_codec_settings"; private static final String TAG = "BtCodecCtr"; + private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U + private final Callback mCallback; public BluetoothCodecDialogPreferenceController(Context context, Lifecycle lifecycle, @@ -118,6 +120,14 @@ public class BluetoothCodecDialogPreferenceController extends codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC; codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; break; + case 6: + codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3; + codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; + break; + case 7: + codecTypeValue = SOURCE_CODEC_TYPE_OPUS; // TODO update in U + codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; + break; default: break; } @@ -180,6 +190,9 @@ public class BluetoothCodecDialogPreferenceController extends case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC: index = 5; break; + case SOURCE_CODEC_TYPE_OPUS: // TODO update in U + index = 7; + break; default: Log.e(TAG, "Unsupported config:" + config); break; diff --git a/src/com/android/settings/deviceinfo/StorageWizardInit.java b/src/com/android/settings/deviceinfo/StorageWizardInit.java index 3a0f7e61df7..962c65ca060 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardInit.java +++ b/src/com/android/settings/deviceinfo/StorageWizardInit.java @@ -76,36 +76,28 @@ public class StorageWizardInit extends StorageWizardBase { } } - @Override - public void onBackPressed() { - if (mPortable) { - super.onBackPressed(); - } else { - mFlipper.showPrevious(); - setBackButtonText(R.string.wizard_back_adoptable); - setHeaderText(R.string.storage_wizard_init_v2_external_title, - getDiskShortDescription()); - setNextButtonText(R.string.storage_wizard_init_v2_external_action); - mPortable = true; - } - } - @Override public void onNavigateBack(View v) { - if (mPortable == false) { - return; - } if (!mIsPermittedToAdopt) { // TODO: Show a message about why this is disabled for guest and // that only an admin user can adopt an sd card. v.setEnabled(false); + } else if (mPortable == false) { + mFlipper.showNext(); + setHeaderText(R.string.storage_wizard_init_v2_external_title, + getDiskShortDescription()); + setNextButtonText(R.string.storage_wizard_init_v2_external_action); + setBackButtonText(R.string.wizard_back_adoptable); + setBackButtonVisibility(View.VISIBLE); + mPortable = true; } else { mFlipper.showNext(); setHeaderText(R.string.storage_wizard_init_v2_internal_title, getDiskShortDescription()); setNextButtonText(R.string.storage_wizard_init_v2_internal_action); - setBackButtonVisibility(View.INVISIBLE); + setBackButtonText(R.string.wizard_back_adoptable); + setBackButtonVisibility(View.VISIBLE); mPortable = false; } } @@ -162,4 +154,4 @@ public class StorageWizardInit extends StorageWizardBase { } return s; } -} +} \ No newline at end of file diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java index 45d145ab0de..84b90c34c87 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java @@ -106,6 +106,10 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro private boolean mIsFooterPrefAdded = false; private PreferenceScreen mPreferenceScreen; private FooterPreference mFooterPreference; + // Daily view model only saves abbreviated day of week texts (e.g. MON). This field saves the + // full day of week texts (e.g. Monday), which is used in category title and battery detail + // page. + private List mDailyTimestampFullTexts; private BatteryChartViewModel mDailyViewModel; private List mHourlyViewModels; @@ -200,8 +204,7 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro mPrefContext = screen.getContext(); mAppListPrefGroup = screen.findPreference(mPreferenceKey); mAppListPrefGroup.setOrderingAsAdded(false); - mAppListPrefGroup.setTitle( - mPrefContext.getString(R.string.battery_app_usage_for_past_24)); + mAppListPrefGroup.setTitle(mPrefContext.getString(R.string.battery_app_usage)); mFooterPreference = screen.findPreference(KEY_FOOTER_PREF); // Removes footer first until usage data is loaded to avoid flashing. if (mFooterPreference != null) { @@ -267,15 +270,20 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro }); Log.d(TAG, "getBatteryLevelData: " + batteryLevelData); if (batteryLevelData == null) { + mDailyTimestampFullTexts = null; mDailyViewModel = null; mHourlyViewModels = null; addFooterPreferenceIfNeeded(false); return; } + mDailyTimestampFullTexts = generateTimestampDayOfWeekTexts( + mContext, batteryLevelData.getDailyBatteryLevels().getTimestamps(), + /* isAbbreviation= */ false); mDailyViewModel = new BatteryChartViewModel( batteryLevelData.getDailyBatteryLevels().getLevels(), generateTimestampDayOfWeekTexts( - mContext, batteryLevelData.getDailyBatteryLevels().getTimestamps()), + mContext, batteryLevelData.getDailyBatteryLevels().getTimestamps(), + /* isAbbreviation= */ true), mDailyChartIndex, BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS); mHourlyViewModels = new ArrayList<>(); @@ -498,8 +506,8 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro // Null means we show all information without a specific time slot. if (slotInformation == null) { return isApp - ? mPrefContext.getString(R.string.battery_app_usage_for_past_24) - : mPrefContext.getString(R.string.battery_system_usage_for_past_24); + ? mPrefContext.getString(R.string.battery_app_usage) + : mPrefContext.getString(R.string.battery_system_usage); } else { return isApp ? mPrefContext.getString(R.string.battery_app_usage_for, slotInformation) @@ -507,9 +515,33 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro } } - private String getSlotInformation() { - // TODO: Generate the right slot information from daily and hourly chart selection. - return null; + @VisibleForTesting + String getSlotInformation() { + if (mDailyTimestampFullTexts == null || mDailyViewModel == null + || mHourlyViewModels == null) { + // No data + return null; + } + if (isAllSelected()) { + return null; + } + + final String selectedDayText = mDailyTimestampFullTexts.get(mDailyChartIndex); + if (mHourlyChartIndex == BatteryChartViewModel.SELECTED_INDEX_ALL) { + return selectedDayText; + } + + final String fromHourText = mHourlyViewModels.get(mDailyChartIndex).texts().get( + mHourlyChartIndex); + final String toHourText = mHourlyViewModels.get(mDailyChartIndex).texts().get( + mHourlyChartIndex + 1); + final String selectedHourText = + String.format("%s%s%s", fromHourText, mIs24HourFormat ? "-" : " - ", toHourText); + if (isBatteryLevelDataInOneDay()) { + return selectedHourText; + } + + return String.format("%s %s", selectedDayText, selectedHourText); } @VisibleForTesting @@ -579,14 +611,20 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro } private boolean isBatteryLevelDataInOneDay() { - return mHourlyViewModels.size() == 1; + return mHourlyViewModels != null && mHourlyViewModels.size() == 1; } - private static List generateTimestampDayOfWeekTexts( - @NonNull final Context context, @NonNull final List timestamps) { + private boolean isAllSelected() { + return (isBatteryLevelDataInOneDay() + || mDailyChartIndex == BatteryChartViewModel.SELECTED_INDEX_ALL) + && mHourlyChartIndex == BatteryChartViewModel.SELECTED_INDEX_ALL; + } + + private static List generateTimestampDayOfWeekTexts(@NonNull final Context context, + @NonNull final List timestamps, final boolean isAbbreviation) { final ArrayList texts = new ArrayList<>(); for (Long timestamp : timestamps) { - texts.add(ConvertUtils.utcToLocalTimeDayOfWeek(context, timestamp)); + texts.add(ConvertUtils.utcToLocalTimeDayOfWeek(context, timestamp, isAbbreviation)); } return texts; } diff --git a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java index b89bfe68bad..8d2013ce793 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java @@ -150,10 +150,12 @@ public final class ConvertUtils { } /** Converts UTC timestamp to local time day of week data. */ - public static String utcToLocalTimeDayOfWeek(final Context context, final long timestamp) { + public static String utcToLocalTimeDayOfWeek( + final Context context, final long timestamp, final boolean isAbbreviation) { final Locale locale = getLocale(context); - final String pattern = DateFormat.getBestDateTimePattern(locale, "E"); - return DateFormat.format(pattern, timestamp).toString().toUpperCase(locale); + final String pattern = DateFormat.getBestDateTimePattern(locale, + isAbbreviation ? "E" : "EEEE"); + return DateFormat.format(pattern, timestamp).toString(); } /** Gets indexed battery usage data for each corresponding time slot. */ diff --git a/src/com/android/settings/nearby/FastPairPreferenceController.java b/src/com/android/settings/nearby/FastPairPreferenceController.java new file mode 100644 index 00000000000..a1152022c6b --- /dev/null +++ b/src/com/android/settings/nearby/FastPairPreferenceController.java @@ -0,0 +1,41 @@ +/* + * 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.nearby; + +import android.content.Context; + +import androidx.lifecycle.LifecycleObserver; + +import com.android.settings.core.BasePreferenceController; + +/** + * {@link BasePreferenceController} for Fast Pair settings. + */ +public class FastPairPreferenceController extends BasePreferenceController implements + LifecycleObserver { + public static final String TAG = "FastPairPrefController"; + public static final String KEY_FAST_PAIR_SETTINGS = "connected_device_fast_pair"; + + public FastPairPreferenceController(Context context) { + super(context, KEY_FAST_PAIR_SETTINGS); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } +} diff --git a/src/com/android/settings/nearby/FastPairSettingsFragment.java b/src/com/android/settings/nearby/FastPairSettingsFragment.java new file mode 100644 index 00000000000..a92833a3db7 --- /dev/null +++ b/src/com/android/settings/nearby/FastPairSettingsFragment.java @@ -0,0 +1,125 @@ +/* + * 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.nearby; + +import android.app.settings.SettingsEnums; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; + +import androidx.annotation.Nullable; +import androidx.preference.Preference; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.widget.MainSwitchPreference; + +import java.util.Objects; + +/** + * Fragment with the top level fast pair settings. + */ +@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) +public class FastPairSettingsFragment extends SettingsPreferenceFragment { + + private static final String TAG = "FastPairSettingsFrag"; + + private static final String SCAN_SWITCH_KEY = "fast_pair_scan_switch"; + private static final String SAVED_DEVICES_PREF_KEY = "saved_devices"; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + MainSwitchPreference mainSwitchPreference = Objects.requireNonNull( + findPreference(SCAN_SWITCH_KEY)); + mainSwitchPreference.setChecked(false); + + Preference savedDevicePref = Objects.requireNonNull( + findPreference(SAVED_DEVICES_PREF_KEY)); + savedDevicePref.setOnPreferenceClickListener(preference -> { + Intent savedDevicesIntent = getSavedDevicesIntent(); + if (savedDevicesIntent != null && getActivity() != null) { + getActivity().startActivity(savedDevicesIntent); + } + return true; + }); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.CONNECTION_DEVICE_ADVANCED_FAST_PAIR; + } + + @Override + public int getHelpResource() { + return 0; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.fast_pair_settings; + } + + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.fast_pair_settings); + + @Nullable + private ComponentName getSavedDevicesComponent() { + String savedDevicesComponent = Settings.Secure.getString( + getContentResolver(), + Settings.Secure.NEARBY_FAST_PAIR_SETTINGS_DEVICES_COMPONENT); + if (TextUtils.isEmpty(savedDevicesComponent)) { + savedDevicesComponent = getString( + com.android.internal.R.string.config_defaultNearbyFastPairSettingsDevicesComponent); + } + + if (TextUtils.isEmpty(savedDevicesComponent)) { + return null; + } + + return ComponentName.unflattenFromString(savedDevicesComponent); + } + + @Nullable + private Intent getSavedDevicesIntent() { + ComponentName componentName = getSavedDevicesComponent(); + if (componentName == null) { + return null; + } + + PackageManager pm = getPackageManager(); + Intent intent = getIntent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setComponent(componentName); + + final ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.GET_META_DATA); + if (resolveInfo == null || resolveInfo.activityInfo == null) { + Log.e(TAG, "Device-specified fast pair component (" + componentName + + ") not available"); + return null; + } + return intent; + } +} diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java index 9e96be99690..e55ea16c15c 100644 --- a/src/com/android/settings/wifi/WifiConfigController2.java +++ b/src/com/android/settings/wifi/WifiConfigController2.java @@ -42,6 +42,7 @@ import android.text.InputType; import android.text.SpannableString; import android.text.TextUtils; import android.text.TextWatcher; +import android.util.ArrayMap; import android.util.Log; import android.view.KeyEvent; import android.view.View; @@ -1495,13 +1496,20 @@ public class WifiConfigController2 implements TextWatcher, } // Shows display name of each active subscription. - final ArrayList displayNames = new ArrayList<>(); + ArrayMap displayNames = new ArrayMap<>(); + int defaultDataSubscriptionId = SubscriptionManager.getDefaultDataSubscriptionId(); for (SubscriptionInfo activeSubInfo : mActiveSubscriptionInfos) { - displayNames.add( + // If multiple SIMs have the same carrier id, only the first or default data SIM is + // displayed. + if (displayNames.containsKey(activeSubInfo.getCarrierId()) + && defaultDataSubscriptionId != activeSubInfo.getSubscriptionId()) { + continue; + } + displayNames.put(activeSubInfo.getCarrierId(), SubscriptionUtil.getUniqueSubscriptionDisplayName(activeSubInfo, mContext)); } mEapSimSpinner.setAdapter( - getSpinnerAdapter(displayNames.toArray(new String[displayNames.size()]))); + getSpinnerAdapter(displayNames.values().toArray(new String[displayNames.size()]))); mEapSimSpinner.setSelection(0 /* position */); if (displayNames.size() == 1) { mEapSimSpinner.setEnabled(false); diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java index f04a80d1988..8da44cc0d87 100644 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java @@ -52,6 +52,8 @@ import java.util.List; @RunWith(RobolectricTestRunner.class) public class BluetoothCodecDialogPreferenceControllerTest { + private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO(b/240635097): remove in U + private static final String DEVICE_ADDRESS = "00:11:22:33:44:55"; @Mock @@ -72,6 +74,7 @@ public class BluetoothCodecDialogPreferenceControllerTest { private BluetoothCodecConfig mCodecConfigAPTX; private BluetoothCodecConfig mCodecConfigAPTXHD; private BluetoothCodecConfig mCodecConfigLDAC; + private BluetoothCodecConfig mCodecConfigOPUS; private BluetoothDevice mActiveDevice; private Context mContext; private LifecycleOwner mLifecycleOwner; @@ -119,13 +122,17 @@ public class BluetoothCodecDialogPreferenceControllerTest { mCodecConfigLDAC = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) .build(); + mCodecConfigOPUS = new BluetoothCodecConfig.Builder() + .setCodecType(SOURCE_CODEC_TYPE_OPUS) + .build(); when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.A2DP))) .thenReturn(Arrays.asList(mActiveDevice)); } @Test public void writeConfigurationValues_selectDefault_setHighest() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC}; + BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC, + mCodecConfigSBC}; mCodecStatus = new BluetoothCodecStatus.Builder() .setCodecConfig(mCodecConfigSBC) .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) @@ -136,13 +143,14 @@ public class BluetoothCodecDialogPreferenceControllerTest { mController.onBluetoothServiceConnected(mBluetoothA2dp); mController.writeConfigurationValues(0); - verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC); + // TODO(b/240635097): update in U + verify(mBluetoothA2dpConfigStore).setCodecType(SOURCE_CODEC_TYPE_OPUS); } @Test public void writeConfigurationValues_checkCodec() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC, mCodecConfigAPTX, - mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigAAC, mCodecConfigSBC}; + BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC, + mCodecConfigSBC, mCodecConfigAPTX, mCodecConfigAPTXHD, mCodecConfigLDAC}; mCodecStatus = new BluetoothCodecStatus.Builder() .setCodecConfig(mCodecConfigSBC) .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) @@ -167,12 +175,15 @@ public class BluetoothCodecDialogPreferenceControllerTest { mController.writeConfigurationValues(5); verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC); + mController.writeConfigurationValues(7); + // TODO(b/240635097): update in U + verify(mBluetoothA2dpConfigStore).setCodecType(SOURCE_CODEC_TYPE_OPUS); } @Test public void writeConfigurationValues_resetHighestConfig() { BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC, mCodecConfigAPTX, - mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigAAC, mCodecConfigSBC}; + mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigOPUS}; mCodecStatus = new BluetoothCodecStatus.Builder() .setCodecConfig(mCodecConfigAAC) .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) @@ -197,6 +208,14 @@ public class BluetoothCodecDialogPreferenceControllerTest { mController.convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)); } + @Test + public void getCurrentIndexByConfig_verifyOpusIndex() { + assertThat(mController.getCurrentIndexByConfig(mCodecConfigOPUS)).isEqualTo( + mController.convertCfgToBtnIndex(SOURCE_CODEC_TYPE_OPUS)); + // TODO(b/240635097): update in U + } + + @Test public void onIndexUpdated_notifyPreference() { mController.onIndexUpdated(0); @@ -204,9 +223,29 @@ public class BluetoothCodecDialogPreferenceControllerTest { verify(mCallback).onBluetoothCodecChanged(); } + @Test + public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsOpus() { + List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, + mCodecConfigAAC, mCodecConfigSBC); + mCodecStatus = new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigOPUS) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); + when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn( + BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); + mController.onBluetoothServiceConnected(mBluetoothA2dp); + + mController.onHDAudioEnabled(/* enabled= */ true); + + verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( + eq(SOURCE_CODEC_TYPE_OPUS)); // TODO(b/240635097): update in U + } + @Test public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsAAC() { - List mCodecConfigs = Arrays.asList(mCodecConfigAAC, mCodecConfigSBC); + List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, + mCodecConfigAAC, mCodecConfigSBC); mCodecStatus = new BluetoothCodecStatus.Builder() .setCodecConfig(mCodecConfigAAC) .setCodecsSelectableCapabilities(mCodecConfigs) @@ -223,7 +262,8 @@ public class BluetoothCodecDialogPreferenceControllerTest { } @Test public void onHDAudioEnabled_optionalCodecDisabled_setsCodecTypeAsSBC() { - List mCodecConfigs = Arrays.asList(mCodecConfigAAC, mCodecConfigSBC); + List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, + mCodecConfigAAC, mCodecConfigSBC); mCodecStatus = new BluetoothCodecStatus.Builder() .setCodecConfig(mCodecConfigAAC) .setCodecsSelectableCapabilities(mCodecConfigs) diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java index 16e04599c43..989790e59cd 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java @@ -188,7 +188,7 @@ public final class BatteryChartPreferenceControllerV2Test { verify(mHourlyChartView, atLeastOnce()).setVisibility(View.GONE); verify(mDailyChartView).setViewModel(new BatteryChartViewModel( List.of(100, 83, 59, 41), - List.of("SAT", "SUN", "MON", "MON"), + List.of("Sat", "Sun", "Mon", "Mon"), BatteryChartViewModel.SELECTED_INDEX_ALL, BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS)); @@ -200,7 +200,7 @@ public final class BatteryChartPreferenceControllerV2Test { verify(mHourlyChartView).setVisibility(View.VISIBLE); verify(mDailyChartView).setViewModel(new BatteryChartViewModel( List.of(100, 83, 59, 41), - List.of("SAT", "SUN", "MON", "MON"), + List.of("Sat", "Sun", "Mon", "Mon"), 0, BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS)); verify(mHourlyChartView).setViewModel(new BatteryChartViewModel( @@ -219,7 +219,7 @@ public final class BatteryChartPreferenceControllerV2Test { verify(mHourlyChartView).setVisibility(View.VISIBLE); verify(mDailyChartView).setViewModel(new BatteryChartViewModel( List.of(100, 83, 59, 41), - List.of("SAT", "SUN", "MON", "MON"), + List.of("Sat", "Sun", "Mon", "Mon"), 1, BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS)); verify(mHourlyChartView).setViewModel(new BatteryChartViewModel( @@ -239,7 +239,7 @@ public final class BatteryChartPreferenceControllerV2Test { verify(mHourlyChartView).setVisibility(View.VISIBLE); verify(mDailyChartView).setViewModel(new BatteryChartViewModel( List.of(100, 83, 59, 41), - List.of("SAT", "SUN", "MON", "MON"), + List.of("Sat", "Sun", "Mon", "Mon"), 2, BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS)); verify(mHourlyChartView).setViewModel(new BatteryChartViewModel( @@ -355,7 +355,7 @@ public final class BatteryChartPreferenceControllerV2Test { } @Test - public void handlePreferenceTreeiClick_notPowerGaugePreference_returnFalse() { + public void handlePreferenceTreeClick_notPowerGaugePreference_returnFalse() { assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(mAppListGroup)) .isFalse(); @@ -523,6 +523,8 @@ public final class BatteryChartPreferenceControllerV2Test { mBatteryChartPreferenceController.mExpandDividerPreference = spy(new ExpandDividerPreference(mContext)); // Simulates select all condition. + mBatteryChartPreferenceController.mDailyChartIndex = + BatteryChartViewModel.SELECTED_INDEX_ALL; mBatteryChartPreferenceController.mHourlyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL; @@ -533,32 +535,88 @@ public final class BatteryChartPreferenceControllerV2Test { verify(mBatteryChartPreferenceController.mAppListPrefGroup) .setTitle(captor.capture()); assertThat(captor.getValue()) - .isEqualTo("App usage for past 24 hr"); + .isEqualTo("App usage since last full charge"); // Verifies the title in the expandable divider. captor = ArgumentCaptor.forClass(String.class); verify(mBatteryChartPreferenceController.mExpandDividerPreference) .setTitle(captor.capture()); assertThat(captor.getValue()) - .isEqualTo("System usage for past 24 hr"); + .isEqualTo("System usage since last full charge"); + } + + @Test + public void selectedSlotText_selectAllDaysAllHours_returnNull() { + mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(60)); + mBatteryChartPreferenceController.mDailyChartIndex = + BatteryChartViewModel.SELECTED_INDEX_ALL; + mBatteryChartPreferenceController.mHourlyChartIndex = + BatteryChartViewModel.SELECTED_INDEX_ALL; + + assertThat(mBatteryChartPreferenceController.getSlotInformation()).isEqualTo(null); + } + + @Test + public void selectedSlotText_onlyOneDayDataSelectAllHours_returnNull() { + mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6)); + mBatteryChartPreferenceController.mDailyChartIndex = 0; + mBatteryChartPreferenceController.mHourlyChartIndex = + BatteryChartViewModel.SELECTED_INDEX_ALL; + + assertThat(mBatteryChartPreferenceController.getSlotInformation()).isEqualTo(null); + } + + @Test + public void selectedSlotText_selectADayAllHours_onlyDayText() { + mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(60)); + mBatteryChartPreferenceController.mDailyChartIndex = 1; + mBatteryChartPreferenceController.mHourlyChartIndex = + BatteryChartViewModel.SELECTED_INDEX_ALL; + + assertThat(mBatteryChartPreferenceController.getSlotInformation()).isEqualTo("Sunday"); + } + + @Test + public void selectedSlotText_onlyOneDayDataSelectAnHour_onlyHourText() { + mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6)); + mBatteryChartPreferenceController.mDailyChartIndex = 0; + mBatteryChartPreferenceController.mHourlyChartIndex = 1; + + assertThat(mBatteryChartPreferenceController.getSlotInformation()).isEqualTo( + "10 am - 12 pm"); + } + + @Test + public void selectedSlotText_SelectADayAnHour_dayAndHourText() { + mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(60)); + mBatteryChartPreferenceController.mDailyChartIndex = 1; + mBatteryChartPreferenceController.mHourlyChartIndex = 8; + + assertThat(mBatteryChartPreferenceController.getSlotInformation()).isEqualTo( + "Sunday 4 pm - 6 pm"); } @Test public void onSaveInstanceState_restoreSelectedIndexAndExpandState() { - final int expectedIndex = 1; + final int expectedDailyIndex = 1; + final int expectedHourlyIndex = 2; final boolean isExpanded = true; final Bundle bundle = new Bundle(); - mBatteryChartPreferenceController.mHourlyChartIndex = expectedIndex; + mBatteryChartPreferenceController.mDailyChartIndex = expectedDailyIndex; + mBatteryChartPreferenceController.mHourlyChartIndex = expectedHourlyIndex; mBatteryChartPreferenceController.mIsExpanded = isExpanded; mBatteryChartPreferenceController.onSaveInstanceState(bundle); // Replaces the original controller with other values. + mBatteryChartPreferenceController.mDailyChartIndex = -1; mBatteryChartPreferenceController.mHourlyChartIndex = -1; mBatteryChartPreferenceController.mIsExpanded = false; mBatteryChartPreferenceController.onCreate(bundle); mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(25)); + assertThat(mBatteryChartPreferenceController.mDailyChartIndex) + .isEqualTo(expectedDailyIndex); assertThat(mBatteryChartPreferenceController.mHourlyChartIndex) - .isEqualTo(expectedIndex); + .isEqualTo(expectedHourlyIndex); assertThat(mBatteryChartPreferenceController.mIsExpanded).isTrue(); } diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java index 5d568fea395..9139a285e14 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java @@ -16,6 +16,8 @@ package com.android.settings.wifi; +import static com.android.settings.wifi.WifiConfigController2.WIFI_EAP_METHOD_SIM; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; @@ -86,6 +88,8 @@ public class WifiConfigController2Test { private AndroidKeystoreAliasLoader mAndroidKeystoreAliasLoader; @Mock private WifiManager mWifiManager; + @Mock + Spinner mEapMethodSimSpinner; private View mView; private Spinner mHiddenSettingsSpinner; private Spinner mEapCaCertSpinner; @@ -141,6 +145,7 @@ public class WifiConfigController2Test { mContext.getString(R.string.wifi_do_not_provide_eap_user_cert); ipSettingsSpinner.setSelection(DHCP); mShadowSubscriptionManager = shadowOf(mContext.getSystemService(SubscriptionManager.class)); + when(mEapMethodSimSpinner.getSelectedItemPosition()).thenReturn(WIFI_EAP_METHOD_SIM); mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry, WifiConfigUiBase2.MODE_CONNECT); @@ -813,10 +818,7 @@ public class WifiConfigController2Test { when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP); mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry, WifiConfigUiBase2.MODE_CONNECT); - final Spinner eapMethodSpinner = mock(Spinner.class); - when(eapMethodSpinner.getSelectedItemPosition()).thenReturn( - WifiConfigController2.WIFI_EAP_METHOD_SIM); - mController.mEapMethodSpinner = eapMethodSpinner; + mController.mEapMethodSpinner = mEapMethodSimSpinner; mController.loadSims(); @@ -837,10 +839,7 @@ public class WifiConfigController2Test { mShadowSubscriptionManager.setActiveSubscriptionInfoList(Arrays.asList(subscriptionInfo)); mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry, WifiConfigUiBase2.MODE_CONNECT); - final Spinner eapMethodSpinner = mock(Spinner.class); - when(eapMethodSpinner.getSelectedItemPosition()).thenReturn( - WifiConfigController2.WIFI_EAP_METHOD_SIM); - mController.mEapMethodSpinner = eapMethodSpinner; + mController.mEapMethodSpinner = mEapMethodSimSpinner; mController.loadSims(); @@ -848,6 +847,48 @@ public class WifiConfigController2Test { assertThat(wifiConfiguration.carrierId).isEqualTo(carrierId); } + @Test + public void loadSims_twoSimsWithDifferentCarrierId_showTwoSims() { + SubscriptionInfo sub1 = createMockSubscription(1, "sub1", 8888); + SubscriptionInfo sub2 = createMockSubscription(2, "sub2", 9999); + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + mShadowSubscriptionManager.setActiveSubscriptionInfoList(Arrays.asList(sub1, sub2)); + when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP); + mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry, + WifiConfigUiBase2.MODE_CONNECT); + mController.mEapMethodSpinner = mEapMethodSimSpinner; + ShadowSubscriptionManager.setDefaultDataSubscriptionId(1); + + mController.loadSims(); + + assertThat(mController.mEapSimSpinner.getAdapter().getCount()).isEqualTo(2); + } + + @Test + public void loadSims_twoSimsWithSameCarrierId_showOneDefaultDataSim() { + SubscriptionInfo sub1 = createMockSubscription(1, "sub1", 9999); + SubscriptionInfo sub2 = createMockSubscription(2, "sub2", 9999); + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + mShadowSubscriptionManager.setActiveSubscriptionInfoList(Arrays.asList(sub1, sub2)); + when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP); + mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry, + WifiConfigUiBase2.MODE_CONNECT); + mController.mEapMethodSpinner = mEapMethodSimSpinner; + ShadowSubscriptionManager.setDefaultDataSubscriptionId(1); + + mController.loadSims(); + + assertThat(mController.mEapSimSpinner.getAdapter().getCount()).isEqualTo(1); + assertThat(mController.mEapSimSpinner.getSelectedItem().toString()).isEqualTo("sub1"); + + ShadowSubscriptionManager.setDefaultDataSubscriptionId(2); + + mController.loadSims(); + + assertThat(mController.mEapSimSpinner.getAdapter().getCount()).isEqualTo(1); + assertThat(mController.mEapSimSpinner.getSelectedItem().toString()).isEqualTo("sub2"); + } + @Test public void loadCaCertificateValue_shouldPersistentAsDefault() { setUpModifyingSavedCertificateConfigController(null, null); @@ -940,4 +981,12 @@ public class WifiConfigController2Test { // certificates are covered by mController.onItemSelected after showSecurityFields end. mController.mEapMethodSpinner.setSelection(Eap.TLS); } + + private SubscriptionInfo createMockSubscription(int subId, String displayName, int carrierId) { + SubscriptionInfo sub = mock(SubscriptionInfo.class); + when(sub.getSubscriptionId()).thenReturn(subId); + when(sub.getDisplayName()).thenReturn(displayName); + when(sub.getCarrierId()).thenReturn(carrierId); + return sub; + } } diff --git a/tests/unit/src/com/android/settings/nearby/FastPairPreferenceControllerTest.java b/tests/unit/src/com/android/settings/nearby/FastPairPreferenceControllerTest.java new file mode 100644 index 00000000000..f06be4b2288 --- /dev/null +++ b/tests/unit/src/com/android/settings/nearby/FastPairPreferenceControllerTest.java @@ -0,0 +1,52 @@ +/* + * 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.nearby; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.os.Looper; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class FastPairPreferenceControllerTest { + + private Context mContext; + private FastPairPreferenceController mController; + + @Before + public void setUp() { + mContext = spy(ApplicationProvider.getApplicationContext()); + mController = new FastPairPreferenceController(mContext); + if (Looper.myLooper() == null) { + Looper.prepare(); + } + } + + @Test + public void isAvailable_shouldBeTrue() { + assertThat(mController.isAvailable()).isTrue(); + } +} diff --git a/tests/unit/src/com/android/settings/nearby/FastPairSettingsFragmentTest.java b/tests/unit/src/com/android/settings/nearby/FastPairSettingsFragmentTest.java new file mode 100644 index 00000000000..faabe8fd9fe --- /dev/null +++ b/tests/unit/src/com/android/settings/nearby/FastPairSettingsFragmentTest.java @@ -0,0 +1,47 @@ +/* + * 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.nearby; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.Instrumentation; +import android.app.settings.SettingsEnums; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class FastPairSettingsFragmentTest { + + private FastPairSettingsFragment mFragment; + + @Before + public void setUp() { + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + instrumentation.runOnMainSync(() -> mFragment = new FastPairSettingsFragment()); + } + + @Test + public void getCategoryKey_isNetwork() { + assertThat(mFragment.getMetricsCategory()) + .isEqualTo(SettingsEnums.CONNECTION_DEVICE_ADVANCED_FAST_PAIR); + } +}