diff --git a/res/color/color_accent_selector.xml b/res/color/color_accent_selector.xml
new file mode 100644
index 00000000000..3ccb64068ec
--- /dev/null
+++ b/res/color/color_accent_selector.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/res/color/color_battery_anomaly_yellow_selector.xml b/res/color/color_battery_anomaly_yellow_selector.xml
new file mode 100644
index 00000000000..0dd79c2fb84
--- /dev/null
+++ b/res/color/color_battery_anomaly_yellow_selector.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/res/drawable/ic_battery_tips_lightbulb.xml b/res/drawable/ic_battery_tips_lightbulb.xml
index f1449f9bb5b..6fffefc8119 100644
--- a/res/drawable/ic_battery_tips_lightbulb.xml
+++ b/res/drawable/ic_battery_tips_lightbulb.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
\ No newline at end of file
diff --git a/res/drawable/ic_battery_tips_warning_icon.xml b/res/drawable/ic_battery_tips_warning_icon.xml
new file mode 100644
index 00000000000..c5df8a8856d
--- /dev/null
+++ b/res/drawable/ic_battery_tips_warning_icon.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/battery_tips_card.xml b/res/layout/battery_tips_card.xml
index 3eb2eb23cfa..c9a00bc6ab9 100644
--- a/res/layout/battery_tips_card.xml
+++ b/res/layout/battery_tips_card.xml
@@ -61,7 +61,7 @@
android:text="@string/battery_tips_card_action_button"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
- app:strokeColor="?android:attr/colorAccent"
+ app:strokeColor="@color/color_accent_selector"
app:strokeWidth="1dp" />
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 47cf21f210b..78e7ca41d13 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1409,6 +1409,17 @@
+
+
+ - ic_battery_tips_lightbulb
+ - ic_battery_tips_warning_icon
+
+
+
+ - color_accent_selector
+ - color_battery_anomaly_yellow_selector
+
+
- Turn on adaptive brightness to extend battery life
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 22c60e2171a..26738d6deb4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6992,7 +6992,7 @@
Languages, gestures, time, backup
- System languages, app languages, speech
+ System languages, app languages, regional preferences, speech
wifi, wi-fi, network connection, internet, wireless, data, wi fi
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java b/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java
index fe0d14182cc..9571767253c 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java
@@ -109,6 +109,7 @@ public class BluetoothDetailsAudioDeviceTypeController extends BluetoothDetailsC
mAudioManager.setBluetoothAudioDeviceCategory(mCachedDevice.getAddress(),
mCachedDevice.getDevice().getType() == DEVICE_TYPE_LE,
Integer.parseInt(value));
+ mCachedDevice.onAudioDeviceCategoryChanged();
}
}
return true;
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java
index a1e133e6104..c431ceeb0ae 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java
@@ -16,6 +16,8 @@
package com.android.settings.bluetooth;
+import static android.media.Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
+
import android.content.Context;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
@@ -51,9 +53,7 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
@VisibleForTesting
PreferenceCategory mProfilesContainer;
@VisibleForTesting
- AudioDeviceAttributes mAudioDevice;
-
- private boolean mIsAvailable;
+ AudioDeviceAttributes mAudioDevice = null;
public BluetoothDetailsSpatialAudioController(
Context context,
@@ -63,13 +63,11 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
super(context, fragment, device, lifecycle);
AudioManager audioManager = context.getSystemService(AudioManager.class);
mSpatializer = audioManager.getSpatializer();
- getAvailableDevice();
-
}
@Override
public boolean isAvailable() {
- return mIsAvailable;
+ return mSpatializer.getImmersiveAudioLevel() != SPATIALIZER_IMMERSIVE_LEVEL_NONE;
}
@Override
@@ -77,15 +75,11 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
SwitchPreference switchPreference = (SwitchPreference) preference;
String key = switchPreference.getKey();
if (TextUtils.equals(key, KEY_SPATIAL_AUDIO)) {
- if (switchPreference.isChecked()) {
- mSpatializer.addCompatibleAudioDevice(mAudioDevice);
- } else {
- mSpatializer.removeCompatibleAudioDevice(mAudioDevice);
- }
- refresh();
+ updateSpatializerEnabled(switchPreference.isChecked());
+ refreshSpatialAudioEnabled(switchPreference);
return true;
} else if (TextUtils.equals(key, KEY_HEAD_TRACKING)) {
- mSpatializer.setHeadTrackerEnabled(switchPreference.isChecked(), mAudioDevice);
+ updateSpatializerHeadTracking(switchPreference.isChecked());
return true;
} else {
Log.w(TAG, "invalid key name.");
@@ -93,6 +87,26 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
}
}
+ private void updateSpatializerEnabled(boolean enabled) {
+ if (mAudioDevice == null) {
+ Log.w(TAG, "cannot update spatializer enabled for null audio device.");
+ return;
+ }
+ if (enabled) {
+ mSpatializer.addCompatibleAudioDevice(mAudioDevice);
+ } else {
+ mSpatializer.removeCompatibleAudioDevice(mAudioDevice);
+ }
+ }
+
+ private void updateSpatializerHeadTracking(boolean enabled) {
+ if (mAudioDevice == null) {
+ Log.w(TAG, "cannot update spatializer head tracking for null audio device.");
+ return;
+ }
+ mSpatializer.setHeadTrackerEnabled(enabled, mAudioDevice);
+ }
+
@Override
public String getPreferenceKey() {
return KEY_SPATIAL_AUDIO_GROUP;
@@ -106,12 +120,31 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
@Override
protected void refresh() {
- SwitchPreference spatialAudioPref = mProfilesContainer.findPreference(KEY_SPATIAL_AUDIO);
- if (spatialAudioPref == null) {
- spatialAudioPref = createSpatialAudioPreference(mProfilesContainer.getContext());
- mProfilesContainer.addPreference(spatialAudioPref);
+ if (mAudioDevice == null) {
+ getAvailableDevice();
}
+ SwitchPreference spatialAudioPref = mProfilesContainer.findPreference(KEY_SPATIAL_AUDIO);
+ if (spatialAudioPref == null && mAudioDevice != null) {
+ spatialAudioPref = createSpatialAudioPreference(mProfilesContainer.getContext());
+ mProfilesContainer.addPreference(spatialAudioPref);
+ } else if (mAudioDevice == null || !mSpatializer.isAvailableForDevice(mAudioDevice)) {
+ if (spatialAudioPref != null) {
+ mProfilesContainer.removePreference(spatialAudioPref);
+ }
+ final SwitchPreference headTrackingPref =
+ mProfilesContainer.findPreference(KEY_HEAD_TRACKING);
+ if (headTrackingPref != null) {
+ mProfilesContainer.removePreference(headTrackingPref);
+ }
+ mAudioDevice = null;
+ return;
+ }
+
+ refreshSpatialAudioEnabled(spatialAudioPref);
+ }
+
+ private void refreshSpatialAudioEnabled(SwitchPreference spatialAudioPref) {
boolean isSpatialAudioOn = mSpatializer.getCompatibleAudioDevices().contains(mAudioDevice);
Log.d(TAG, "refresh() isSpatialAudioOn : " + isSpatialAudioOn);
spatialAudioPref.setChecked(isSpatialAudioOn);
@@ -121,9 +154,13 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
headTrackingPref = createHeadTrackingPreference(mProfilesContainer.getContext());
mProfilesContainer.addPreference(headTrackingPref);
}
+ refreshHeadTracking(spatialAudioPref, headTrackingPref);
+ }
+ private void refreshHeadTracking(SwitchPreference spatialAudioPref,
+ SwitchPreference headTrackingPref) {
boolean isHeadTrackingAvailable =
- isSpatialAudioOn && mSpatializer.hasHeadTracker(mAudioDevice);
+ spatialAudioPref.isChecked() && mSpatializer.hasHeadTracker(mAudioDevice);
Log.d(TAG, "refresh() has head tracker : " + mSpatializer.hasHeadTracker(mAudioDevice));
headTrackingPref.setVisible(isHeadTrackingAvailable);
if (isHeadTrackingAvailable) {
@@ -173,7 +210,6 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
AudioDeviceInfo.TYPE_HEARING_AID,
mCachedDevice.getAddress());
- mIsAvailable = true;
if (mSpatializer.isAvailableForDevice(bleHeadsetDevice)) {
mAudioDevice = bleHeadsetDevice;
} else if (mSpatializer.isAvailableForDevice(bleSpeakerDevice)) {
@@ -182,20 +218,20 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont
mAudioDevice = bleBroadcastDevice;
} else if (mSpatializer.isAvailableForDevice(a2dpDevice)) {
mAudioDevice = a2dpDevice;
- } else {
- mIsAvailable = mSpatializer.isAvailableForDevice(hearingAidDevice);
+ } else if (mSpatializer.isAvailableForDevice(hearingAidDevice)) {
mAudioDevice = hearingAidDevice;
+ } else {
+ mAudioDevice = null;
}
Log.d(TAG, "getAvailableDevice() device : "
+ mCachedDevice.getDevice().getAnonymizedAddress()
- + ", type : " + mAudioDevice.getType()
- + ", is available : " + mIsAvailable);
+ + ", is available : " + (mAudioDevice != null)
+ + ", type : " + (mAudioDevice == null ? "no type" : mAudioDevice.getType()));
}
@VisibleForTesting
void setAvailableDevice(AudioDeviceAttributes audioDevice) {
mAudioDevice = audioDevice;
- mIsAvailable = mSpatializer.isAvailableForDevice(audioDevice);
}
}
diff --git a/src/com/android/settings/core/SettingsUIDeviceConfig.java b/src/com/android/settings/core/SettingsUIDeviceConfig.java
index 404b0b4ef39..4d963856b96 100644
--- a/src/com/android/settings/core/SettingsUIDeviceConfig.java
+++ b/src/com/android/settings/core/SettingsUIDeviceConfig.java
@@ -47,4 +47,9 @@ public class SettingsUIDeviceConfig {
*/
public static final String BT_LE_AUDIO_DEVICE_DETAIL_ENABLED =
"bt_le_audio_device_detail_enabled";
+ /**
+ * {@code true} if long press home button to search is enabled.
+ */
+ public static final String LONG_PRESS_HOME_BUTTON_TO_SEARCH =
+ "long_press_home_button_to_search";
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
index 075b7061133..ea5534d6a60 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
@@ -23,6 +23,7 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -51,6 +52,8 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
private String mAnomalyEventId;
private PowerAnomalyKey mPowerAnomalyKey;
+ private int mIconResourceId = 0;
+ private int mMainButtonStrokeColorResourceId = 0;
@VisibleForTesting
CharSequence mMainButtonLabel;
@@ -73,6 +76,26 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
mPowerAnomalyKey = null;
}
+ /**
+ * Sets the icon in tips card.
+ */
+ public void setIconResourceId(int resourceId) {
+ if (mIconResourceId != resourceId) {
+ mIconResourceId = resourceId;
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Sets the stroke color of main button in tips card.
+ */
+ public void setMainButtonStrokeColorResourceId(int resourceId) {
+ if (mMainButtonStrokeColorResourceId != resourceId) {
+ mMainButtonStrokeColorResourceId = resourceId;
+ notifyChanged();
+ }
+ }
+
/**
* Sets the anomaly event id which is used in metrics.
*/
@@ -159,9 +182,15 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
MaterialButton mainButton = (MaterialButton) view.findViewById(R.id.main_button);
mainButton.setOnClickListener(this);
mainButton.setText(mMainButtonLabel);
+ if (mMainButtonStrokeColorResourceId != 0) {
+ mainButton.setStrokeColorResource(mMainButtonStrokeColorResourceId);
+ }
MaterialButton dismissButton = (MaterialButton) view.findViewById(R.id.dismiss_button);
dismissButton.setOnClickListener(this);
dismissButton.setText(mDismissButtonLabel);
+ if (mIconResourceId != 0) {
+ ((ImageView) view.findViewById(R.id.icon)).setImageResource(mIconResourceId);
+ }
if (!mPowerUsageFeatureProvider.isBatteryTipsFeedbackEnabled()) {
return;
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
index 9e46f9064d6..80b26950383 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
@@ -77,23 +77,29 @@ public class BatteryTipsController extends BasePreferenceController {
return null;
}
+ private String getStringFromResource(int resourceId, int resourceIndex) {
+ if (resourceId < 0) {
+ return null;
+ }
+ final String[] stringArray = mContext.getResources().getStringArray(resourceId);
+ return (resourceIndex >= 0 && resourceIndex < stringArray.length)
+ ? stringArray[resourceIndex] : null;
+ }
+
+ private int getResourceId(int resourceId, int resourceIndex, String defType) {
+ final String key = getStringFromResource(resourceId, resourceIndex);
+ return TextUtils.isEmpty(key) ? 0
+ : mContext.getResources().getIdentifier(key, defType, mContext.getPackageName());
+ }
+
private String getString(PowerAnomalyEvent powerAnomalyEvent,
Function warningBannerInfoSupplier,
Function warningItemInfoSupplier,
int resourceId, int resourceIndex) {
String string =
getInfo(powerAnomalyEvent, warningBannerInfoSupplier, warningItemInfoSupplier);
-
- if (!TextUtils.isEmpty(string) || resourceId < 0) {
- return string;
- }
-
- String[] stringArray = mContext.getResources().getStringArray(resourceId);
- if (resourceIndex >= 0 && resourceIndex < stringArray.length) {
- string = stringArray[resourceIndex];
- }
-
- return string;
+ return (!TextUtils.isEmpty(string) || resourceId < 0) ? string
+ : getStringFromResource(resourceId, resourceIndex);
}
@VisibleForTesting
@@ -107,6 +113,13 @@ public class BatteryTipsController extends BasePreferenceController {
return;
}
+ // Get card icon and color styles
+ final int cardStyleId = powerAnomalyEvent.getType().getNumber();
+ final int iconResId = getResourceId(
+ R.array.battery_tips_card_icons, cardStyleId, "drawable");
+ final int colorResId = getResourceId(
+ R.array.battery_tips_card_colors, cardStyleId, "color");
+
// Get card preference strings and navigate fragment info
final PowerAnomalyKey powerAnomalyKey = powerAnomalyEvent.hasKey()
? powerAnomalyEvent.getKey() : null;
@@ -133,10 +146,12 @@ public class BatteryTipsController extends BasePreferenceController {
String preferenceHighlightKey = getInfo(powerAnomalyEvent,
WarningBannerInfo::getMainButtonSourceHighlightKey, null);
- // Updated card preference and main button fragment launcher
+ // Update card preference and main button fragment launcher
mCardPreference.setAnomalyEventId(powerAnomalyEvent.getEventId());
mCardPreference.setPowerAnomalyKey(powerAnomalyKey);
mCardPreference.setTitle(titleString);
+ mCardPreference.setIconResourceId(iconResId);
+ mCardPreference.setMainButtonStrokeColorResourceId(colorResId);
mCardPreference.setMainButtonLabel(mainBtnString);
mCardPreference.setDismissButtonLabel(dismissBtnString);
mCardPreference.setMainButtonLauncherInfo(
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java
index 1f0adcfca80..ce5631fd028 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java
@@ -16,6 +16,9 @@
package com.android.settings.bluetooth;
+import static android.media.Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL;
+import static android.media.Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
@@ -62,6 +65,8 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
@Mock
private BluetoothDevice mBluetoothDevice;
+ private AudioDeviceAttributes mAvailableDevice;
+
private BluetoothDetailsSpatialAudioController mController;
private SwitchPreference mSpatialAudioPref;
private SwitchPreference mHeadTrackingPref;
@@ -86,94 +91,32 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
when(mProfilesContainer.findPreference(KEY_SPATIAL_AUDIO)).thenReturn(mSpatialAudioPref);
when(mProfilesContainer.findPreference(KEY_HEAD_TRACKING)).thenReturn(mHeadTrackingPref);
- }
- @Test
- public void isAvailable_spatialAudioSupportA2dpDevice_returnsTrue() {
- AudioDeviceAttributes a2dpDevice = new AudioDeviceAttributes(
+ mAvailableDevice = new AudioDeviceAttributes(
AudioDeviceAttributes.ROLE_OUTPUT,
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
MAC_ADDRESS);
- when(mSpatializer.isAvailableForDevice(a2dpDevice)).thenReturn(true);
-
- mController.setAvailableDevice(a2dpDevice);
-
- assertThat(mController.isAvailable()).isTrue();
- assertThat(mController.mAudioDevice.getType())
- .isEqualTo(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
}
@Test
- public void isAvailable_spatialAudioSupportBleHeadsetDevice_returnsTrue() {
- AudioDeviceAttributes bleHeadsetDevice = new AudioDeviceAttributes(
- AudioDeviceAttributes.ROLE_OUTPUT,
- AudioDeviceInfo.TYPE_BLE_HEADSET,
- MAC_ADDRESS);
- when(mSpatializer.isAvailableForDevice(bleHeadsetDevice)).thenReturn(true);
-
- mController.setAvailableDevice(bleHeadsetDevice);
-
- assertThat(mController.isAvailable()).isTrue();
- assertThat(mController.mAudioDevice.getType())
- .isEqualTo(AudioDeviceInfo.TYPE_BLE_HEADSET);
- }
-
- @Test
- public void isAvailable_spatialAudioSupportBleSpeakerDevice_returnsTrue() {
- AudioDeviceAttributes bleSpeakerDevice = new AudioDeviceAttributes(
- AudioDeviceAttributes.ROLE_OUTPUT,
- AudioDeviceInfo.TYPE_BLE_SPEAKER,
- MAC_ADDRESS);
- when(mSpatializer.isAvailableForDevice(bleSpeakerDevice)).thenReturn(true);
-
- mController.setAvailableDevice(bleSpeakerDevice);
-
- assertThat(mController.isAvailable()).isTrue();
- assertThat(mController.mAudioDevice.getType())
- .isEqualTo(AudioDeviceInfo.TYPE_BLE_SPEAKER);
- }
-
- @Test
- public void isAvailable_spatialAudioSupportBleBroadcastDevice_returnsTrue() {
- AudioDeviceAttributes bleBroadcastDevice = new AudioDeviceAttributes(
- AudioDeviceAttributes.ROLE_OUTPUT,
- AudioDeviceInfo.TYPE_BLE_BROADCAST,
- MAC_ADDRESS);
- when(mSpatializer.isAvailableForDevice(bleBroadcastDevice)).thenReturn(true);
-
- mController.setAvailableDevice(bleBroadcastDevice);
-
- assertThat(mController.isAvailable()).isTrue();
- assertThat(mController.mAudioDevice.getType())
- .isEqualTo(AudioDeviceInfo.TYPE_BLE_BROADCAST);
- }
-
- @Test
- public void isAvailable_spatialAudioSupportHearingAidDevice_returnsTrue() {
- AudioDeviceAttributes hearingAidDevice = new AudioDeviceAttributes(
- AudioDeviceAttributes.ROLE_OUTPUT,
- AudioDeviceInfo.TYPE_HEARING_AID,
- MAC_ADDRESS);
- when(mSpatializer.isAvailableForDevice(hearingAidDevice)).thenReturn(true);
-
- mController.setAvailableDevice(hearingAidDevice);
-
- assertThat(mController.isAvailable()).isTrue();
- assertThat(mController.mAudioDevice.getType())
- .isEqualTo(AudioDeviceInfo.TYPE_HEARING_AID);
- }
-
- @Test
- public void isAvailable_spatialAudioNotSupported_returnsFalse() {
+ public void isAvailable_forSpatializerWithLevelNone_returnsFalse() {
+ when(mSpatializer.getImmersiveAudioLevel()).thenReturn(SPATIALIZER_IMMERSIVE_LEVEL_NONE);
assertThat(mController.isAvailable()).isFalse();
- assertThat(mController.mAudioDevice.getType())
- .isEqualTo(AudioDeviceInfo.TYPE_HEARING_AID);
+ }
+
+ @Test
+ public void isAvailable_forSpatializerWithLevelNotNone_returnsTrue() {
+ when(mSpatializer.getImmersiveAudioLevel()).thenReturn(
+ SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL);
+ assertThat(mController.isAvailable()).isTrue();
}
@Test
public void refresh_spatialAudioIsTurnedOn_checksSpatialAudioPreference() {
List compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
+ when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
mController.refresh();
@@ -207,13 +150,14 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
public void
refresh_spatialAudioOnAndHeadTrackingIsNotAvailable_hidesHeadTrackingPreference() {
List compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(false);
mController.refresh();
- assertThat(mHeadTrackingPref.isVisible()).isFalse();
+ verify(mProfilesContainer).removePreference(mHeadTrackingPref);
}
@Test
@@ -223,14 +167,16 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
mController.refresh();
- assertThat(mHeadTrackingPref.isVisible()).isFalse();
+ verify(mProfilesContainer).removePreference(mHeadTrackingPref);
}
@Test
public void refresh_headTrackingIsTurnedOn_checksHeadTrackingPreference() {
List compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
+ when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.isHeadTrackerEnabled(mController.mAudioDevice)).thenReturn(true);
@@ -242,8 +188,10 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
@Test
public void refresh_headTrackingIsTurnedOff_unchecksHeadTrackingPreference() {
List compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
+ when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.isHeadTrackerEnabled(mController.mAudioDevice)).thenReturn(false);
@@ -254,6 +202,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
@Test
public void turnedOnSpatialAudio_invokesAddCompatibleAudioDevice() {
+ mController.setAvailableDevice(mAvailableDevice);
mSpatialAudioPref.setChecked(true);
mController.onPreferenceClick(mSpatialAudioPref);
verify(mSpatializer).addCompatibleAudioDevice(mController.mAudioDevice);
@@ -261,6 +210,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
@Test
public void turnedOffSpatialAudio_invokesRemoveCompatibleAudioDevice() {
+ mController.setAvailableDevice(mAvailableDevice);
mSpatialAudioPref.setChecked(false);
mController.onPreferenceClick(mSpatialAudioPref);
verify(mSpatializer).removeCompatibleAudioDevice(mController.mAudioDevice);
@@ -268,6 +218,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
@Test
public void turnedOnHeadTracking_invokesSetHeadTrackerEnabled_setsTrue() {
+ mController.setAvailableDevice(mAvailableDevice);
mHeadTrackingPref.setChecked(true);
mController.onPreferenceClick(mHeadTrackingPref);
verify(mSpatializer).setHeadTrackerEnabled(true, mController.mAudioDevice);
@@ -275,6 +226,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails
@Test
public void turnedOffHeadTracking_invokesSetHeadTrackerEnabled_setsFalse() {
+ mController.setAvailableDevice(mAvailableDevice);
mHeadTrackingPref.setChecked(false);
mController.onPreferenceClick(mHeadTrackingPref);
verify(mSpatializer).setHeadTrackerEnabled(false, mController.mAudioDevice);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
index e1ba84e7dbf..ac9de1fa336 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.LocaleList;
+import com.android.settings.R;
import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -83,6 +84,9 @@ public final class BatteryTipsControllerTest {
// Check pre-defined string
verify(mBatteryTipsCardPreference).setTitle(
"Turn on adaptive brightness to extend battery life");
+ verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
+ verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
+ R.color.color_accent_selector);
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
// Check proto info
@@ -103,6 +107,9 @@ public final class BatteryTipsControllerTest {
verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life");
+ verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
+ verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
+ R.color.color_accent_selector);
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
@@ -129,6 +136,9 @@ public final class BatteryTipsControllerTest {
verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
verify(mBatteryTipsCardPreference).setTitle(testTitle);
+ verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
+ verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
+ R.color.color_accent_selector);
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
@@ -138,4 +148,27 @@ public final class BatteryTipsControllerTest {
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly");
}
+
+ @Test
+ public void handleBatteryTipsCardUpdated_appAnomaly_showAnomaly() {
+ PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+ when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+
+ mBatteryTipsController.handleBatteryTipsCardUpdated(event);
+
+ verify(mBatteryTipsCardPreference).setAnomalyEventId("AppAnomaly");
+ verify(mBatteryTipsCardPreference).setTitle(
+ "Chrome used more battery than usual in foreground");
+ verify(mBatteryTipsCardPreference).setIconResourceId(
+ R.drawable.ic_battery_tips_warning_icon);
+ verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
+ R.color.color_battery_anomaly_yellow_selector);
+ verify(mBatteryTipsCardPreference).setMainButtonLabel("Check");
+ verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
+ verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
+ null, null, null);
+ verify(mBatteryTipsCardPreference).setVisible(true);
+ verify(mFeatureFactory.metricsFeatureProvider).action(
+ mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "AppAnomaly");
+ }
}
diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
index 136431dfa19..3297d1ef4de 100644
--- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
@@ -39,6 +39,7 @@ import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEventList;
import com.android.settings.fuelgauge.batteryusage.PowerAnomalyKey;
import com.android.settings.fuelgauge.batteryusage.PowerAnomalyType;
import com.android.settings.fuelgauge.batteryusage.WarningBannerInfo;
+import com.android.settings.fuelgauge.batteryusage.WarningItemInfo;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
@@ -70,14 +71,18 @@ public class BatteryTestUtils {
BatteryManager.BATTERY_STATUS_DISCHARGING);
}
- /** Sets the work profile mode. */
+ /**
+ * Sets the work profile mode.
+ */
public static void setWorkProfile(Context context) {
final UserManager userManager = context.getSystemService(UserManager.class);
Shadows.shadowOf(userManager).setManagedProfile(true);
Shadows.shadowOf(userManager).setIsSystemUser(false);
}
- /** Creates and sets up the in-memory {@link BatteryStateDatabase}. */
+ /**
+ * Creates and sets up the in-memory {@link BatteryStateDatabase}.
+ */
public static BatteryStateDatabase setUpBatteryStateDatabase(Context context) {
final BatteryStateDatabase inMemoryDatabase =
Room.inMemoryDatabaseBuilder(context, BatteryStateDatabase.class)
@@ -87,21 +92,27 @@ public class BatteryTestUtils {
return inMemoryDatabase;
}
- /** Inserts a fake data into the database for testing. */
+ /**
+ * Inserts a fake data into the database for testing.
+ */
public static void insertDataToBatteryStateTable(
Context context, long timestamp, String packageName) {
insertDataToBatteryStateTable(
context, timestamp, packageName, /*multiple=*/ false, /*isFullChargeStart=*/ false);
}
- /** Inserts a fake data into the database for testing. */
+ /**
+ * Inserts a fake data into the database for testing.
+ */
public static void insertDataToBatteryStateTable(
Context context, long timestamp, String packageName, boolean isFullChargeStart) {
insertDataToBatteryStateTable(
context, timestamp, packageName, /*multiple=*/ false, isFullChargeStart);
}
- /** Inserts a fake data into the database for testing. */
+ /**
+ * Inserts a fake data into the database for testing.
+ */
public static void insertDataToBatteryStateTable(
Context context, long timestamp, String packageName, boolean multiple,
boolean isFullChargeStart) {
@@ -151,14 +162,18 @@ public class BatteryTestUtils {
}
}
- /** Inserts a fake data into the database for testing. */
+ /**
+ * Inserts a fake data into the database for testing.
+ */
public static void insertDataToAppUsageEventTable(
Context context, long userId, long timestamp, String packageName) {
insertDataToAppUsageEventTable(
context, userId, timestamp, packageName, /*multiple=*/ false);
}
- /** Inserts a fake data into the database for testing. */
+ /**
+ * Inserts a fake data into the database for testing.
+ */
public static void insertDataToAppUsageEventTable(
Context context, long userId, long timestamp, String packageName, boolean multiple) {
final AppUsageEventEntity entity =
@@ -179,7 +194,9 @@ public class BatteryTestUtils {
}
}
- /** Gets customized battery changed intent. */
+ /**
+ * Gets customized battery changed intent.
+ */
public static Intent getCustomBatteryIntent(int plugged, int level, int scale, int status) {
Intent intent = new Intent();
intent.putExtra(BatteryManager.EXTRA_PLUGGED, plugged);
@@ -190,7 +207,9 @@ public class BatteryTestUtils {
return intent;
}
- /** Configures the incompatible charger environment. */
+ /**
+ * Configures the incompatible charger environment.
+ */
public static void setupIncompatibleEvent(
UsbPort mockUsbPort, UsbManager mockUsbManager, UsbPortStatus mockUsbPortStatus) {
final List usbPorts = new ArrayList<>();
@@ -203,12 +222,16 @@ public class BatteryTestUtils {
.thenReturn(new int[]{UsbPortStatus.COMPLIANCE_WARNING_OTHER});
}
- /** Create an empty power anomaly event list proto. */
+ /**
+ * Create an empty power anomaly event list proto.
+ */
public static PowerAnomalyEventList createEmptyPowerAnomalyEventList() {
return PowerAnomalyEventList.getDefaultInstance();
}
- /** Create an non-empty power anomaly event list proto. */
+ /**
+ * Create an non-empty power anomaly event list proto.
+ */
public static PowerAnomalyEventList createNonEmptyPowerAnomalyEventList() {
return PowerAnomalyEventList.newBuilder()
.addPowerAnomalyEvents(0, createAdaptiveBrightnessAnomalyEvent())
@@ -216,7 +239,9 @@ public class BatteryTestUtils {
.build();
}
- /** Create a power anomaly event proto of adaptive brightness. */
+ /**
+ * Create a power anomaly event proto of adaptive brightness.
+ */
public static PowerAnomalyEvent createAdaptiveBrightnessAnomalyEvent() {
return PowerAnomalyEvent.newBuilder()
.setEventId("BrightnessAnomaly")
@@ -231,7 +256,9 @@ public class BatteryTestUtils {
.build();
}
- /** Create a power anomaly event proto of screen timeout. */
+ /**
+ * Create a power anomaly event proto of screen timeout.
+ */
public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent() {
return PowerAnomalyEvent.newBuilder()
.setEventId("ScreenTimeoutAnomaly")
@@ -245,4 +272,21 @@ public class BatteryTestUtils {
.build())
.build();
}
+
+ /**
+ * Create a power anomaly event proto of app anomaly.
+ */
+ public static PowerAnomalyEvent createAppAnomalyEvent() {
+ return PowerAnomalyEvent.newBuilder()
+ .setEventId("AppAnomaly")
+ .setType(PowerAnomalyType.TYPE_APPS_ITEM)
+ .setKey(PowerAnomalyKey.KEY_APP)
+ .setScore(2.0f)
+ .setWarningItemInfo(WarningItemInfo.newBuilder()
+ .setTitleString("Chrome used more battery than usual in foreground")
+ .setMainButtonString("Check")
+ .setCancelButtonString("Got it")
+ .build())
+ .build();
+ }
}