Merge "Fix a typo in AndroidManifest.xml" into pi-dev
diff --git a/res/layout/two_state_button.xml b/res/layout/two_state_button.xml
index 22bf2bd..3ad1634 100644
--- a/res/layout/two_state_button.xml
+++ b/res/layout/two_state_button.xml
@@ -27,19 +27,15 @@
<Button
android:id="@+id/state_on_button"
style="@style/ActionPrimaryButton"
- android:layout_width="0dp"
- android:layout_weight="1"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:paddingEnd="8dp" />
+ android:layout_gravity="center" />
<Button
android:id="@+id/state_off_button"
style="@style/ActionSecondaryButton"
- android:layout_width="0dp"
- android:layout_weight="1"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:paddingEnd="8dp" />
+ android:layout_gravity="center" />
</LinearLayout>
\ No newline at end of file
diff --git a/res/values/config.xml b/res/values/config.xml
index e3ec74f..f8a7acc 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -131,4 +131,7 @@
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
<string-array name="config_settings_slices_accessibility_components" translatable="false"/>
+ <!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
+ <bool name="config_swipe_up_gesture_setting_available">false</bool>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b061e61..5c33e9c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7928,6 +7928,15 @@
<!-- [CHAR LIMIT=20] Zen mode settings: Calls screen footer -->
<string name="zen_mode_calls_footer">When Do Not Disturb is on, incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Starred contacts preference title -->
+ <string name="zen_mode_starred_contacts_title">Starred contacts</string>
+
+ <!-- Zen mode settings: Starred contacts summary [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_starred_contacts_summary_additional_contacts">
+ <item quantity="one">and 1 other</item>
+ <item quantity="other">and <xliff:g id="num_people" example="3">%d</xliff:g> others</item>
+ </plurals>
+
<!-- [CHAR LIMIT=20] Zen mode settings: Messages option -->
<string name="zen_mode_messages">Messages</string>
@@ -9199,7 +9208,7 @@
<!-- Informational text about time left in billing cycle [CHAR LIMIT=60] -->
<string name="billing_cycle_less_than_one_day_left">Less than 1 day left</string>
- <!-- Informational text about carrier and update time [CHAR LIMIT=30] -->
+ <!-- Informational text about carrier and update time [CHAR LIMIT=32] -->
<string name="carrier_and_update_text">Updated by <xliff:g name="carrier" example="T-mobile">^1</xliff:g> <xliff:g name="time" example="3m">^2</xliff:g> ago</string>
<!-- Informational text about update time only, without carrier. First argument intentionally skipped. [CHAR LIMIT=30] -->
diff --git a/res/xml/zen_mode_calls_settings.xml b/res/xml/zen_mode_calls_settings.xml
index d9e47f3..62d9ef4 100644
--- a/res/xml/zen_mode_calls_settings.xml
+++ b/res/xml/zen_mode_calls_settings.xml
@@ -29,7 +29,9 @@
android:entries="@array/zen_mode_contacts_entries"
android:entryValues="@array/zen_mode_contacts_values"/>
- <!-- TODO: setting that links to contacts or placeholder for external app -->
+ <Preference
+ android:key="zen_mode_starred_contacts"
+ android:title="@string/zen_mode_starred_contacts_title"/>
<!-- Repeat callers -->
<SwitchPreference
diff --git a/res/xml/zen_mode_msg_event_reminder_settings.xml b/res/xml/zen_mode_msg_event_reminder_settings.xml
index 866f333..2f065a6 100644
--- a/res/xml/zen_mode_msg_event_reminder_settings.xml
+++ b/res/xml/zen_mode_msg_event_reminder_settings.xml
@@ -29,6 +29,10 @@
android:entries="@array/zen_mode_contacts_entries"
android:entryValues="@array/zen_mode_contacts_values"/>
+ <Preference
+ android:key="zen_mode_starred_contacts"
+ android:title="@string/zen_mode_starred_contacts_title"/>
+
<!-- Reminders -->
<SwitchPreference
android:key="zen_mode_reminders"
diff --git a/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java b/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java
index 6b9a480..ec988cd 100644
--- a/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java
@@ -23,7 +23,6 @@
import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
-import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.accessibility.AccessibilityUtils;
@@ -88,7 +87,7 @@
@Override
public int getAvailabilityStatus() {
// Return unsupported when the service is disabled or not installed.
- return getAccessibilityServiceInfo() == null ? DISABLED_UNSUPPORTED : AVAILABLE;
+ return getAccessibilityServiceInfo() == null ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
}
private AccessibilityServiceInfo getAccessibilityServiceInfo() {
diff --git a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
index 947893d..84063a1 100644
--- a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
@@ -56,7 +56,7 @@
public int getAvailabilityStatus() {
return MagnificationPreferenceFragment.isApplicable(mContext.getResources())
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/applications/DataSaverController.java b/src/com/android/settings/applications/DataSaverController.java
index d9710fc..87589a7 100644
--- a/src/com/android/settings/applications/DataSaverController.java
+++ b/src/com/android/settings/applications/DataSaverController.java
@@ -35,6 +35,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_data_saver)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/DeviceAdministratorsController.java b/src/com/android/settings/applications/DeviceAdministratorsController.java
index c7ef8ce..79c078e 100644
--- a/src/com/android/settings/applications/DeviceAdministratorsController.java
+++ b/src/com/android/settings/applications/DeviceAdministratorsController.java
@@ -34,6 +34,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_device_administrators)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/EnabledVrListenersController.java b/src/com/android/settings/applications/EnabledVrListenersController.java
index 94a70ef..0aae14f 100644
--- a/src/com/android/settings/applications/EnabledVrListenersController.java
+++ b/src/com/android/settings/applications/EnabledVrListenersController.java
@@ -34,6 +34,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_enabled_vr_listeners)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/HighPowerAppsController.java b/src/com/android/settings/applications/HighPowerAppsController.java
index dc847b3..b7ec2fb 100644
--- a/src/com/android/settings/applications/HighPowerAppsController.java
+++ b/src/com/android/settings/applications/HighPowerAppsController.java
@@ -34,6 +34,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_high_power_apps)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/PremiumSmsController.java b/src/com/android/settings/applications/PremiumSmsController.java
index 40911a5..ecf19ff 100644
--- a/src/com/android/settings/applications/PremiumSmsController.java
+++ b/src/com/android/settings/applications/PremiumSmsController.java
@@ -34,6 +34,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_premium_sms)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
index afcf760..b0bb173 100644
--- a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
@@ -78,7 +78,7 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_app_info_settings_battery)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java
index a40562a..69be98d 100644
--- a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java
@@ -56,7 +56,7 @@
@Override
public int getAvailabilityStatus() {
- return isBandwidthControlEnabled() ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isBandwidthControlEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/applications/appinfo/AppMemoryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppMemoryPreferenceController.java
index daf3992..4bc680c 100644
--- a/src/com/android/settings/applications/appinfo/AppMemoryPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppMemoryPreferenceController.java
@@ -105,11 +105,11 @@
@Override
public int getAvailabilityStatus() {
if (!mContext.getResources().getBoolean(R.bool.config_show_app_info_settings_memory)) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java b/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java
index cf1731d..d5061d5 100644
--- a/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java
+++ b/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBase.java
@@ -46,7 +46,7 @@
if (UserManager.get(mContext).isManagedProfile()) {
return DISABLED_FOR_USER;
}
- return hasAppCapability() ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return hasAppCapability() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java b/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
index 0997e60..0c4044a 100644
--- a/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
@@ -55,19 +55,19 @@
@Override
public int getAvailabilityStatus() {
if (TextUtils.isEmpty(mPackageName)) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
final List<ResolveInfo> resolved = mPackageManager.queryIntentActivities(mIntent,
0 /* flags */);
if (resolved == null || resolved.isEmpty()) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
for (ResolveInfo info : resolved) {
if (isSystemApp(info)) {
return AVAILABLE;
}
}
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java b/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java
index 183d13f..f0439d6 100644
--- a/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java
+++ b/src/com/android/settings/backup/BackupSettingsActivityPreferenceController.java
@@ -41,7 +41,7 @@
public int getAvailabilityStatus() {
return mUm.isAdminUser()
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
index f2f220a..8827a71 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
@@ -99,7 +99,7 @@
@Override
public int getAvailabilityStatus() {
- return mLocalAdapter != null ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return mLocalAdapter != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
index 6fbb84a..cacfa0c 100644
--- a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
@@ -26,7 +26,6 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/**
@@ -57,7 +56,7 @@
public int getAvailabilityStatus() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/AddDevicePreferenceController.java b/src/com/android/settings/connecteddevice/AddDevicePreferenceController.java
index 2de271c..da6d86f 100644
--- a/src/com/android/settings/connecteddevice/AddDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/AddDevicePreferenceController.java
@@ -75,7 +75,7 @@
public int getAvailabilityStatus() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
index e4bf71c..6fa7d1b 100644
--- a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
@@ -84,7 +84,7 @@
public int getAvailabilityStatus() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
index ec616c8..77b75c5 100644
--- a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
@@ -128,7 +128,7 @@
BluetoothAdapter adapter = manager.getAdapter();
final int status = adapter != null
? TogglePreferenceController.AVAILABLE
- : TogglePreferenceController.DISABLED_UNSUPPORTED;
+ : TogglePreferenceController.UNSUPPORTED_ON_DEVICE;
if (status != TogglePreferenceController.AVAILABLE) {
keys.add(KEY_BLUETOOTH_SCREEN);
}
diff --git a/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java b/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java
index 072de75..6d4e8b8 100644
--- a/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceController.java
@@ -38,7 +38,7 @@
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.BLUETOOTH_WHILE_DRIVING)) {
return AVAILABLE;
}
- return DISABLED_UNSUPPORTED;
+ return CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
index 47e3438..e97683d 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
@@ -33,7 +33,6 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
-import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
/**
@@ -88,7 +87,7 @@
public int getAvailabilityStatus() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java
index f80c877..1826be5 100644
--- a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java
@@ -30,7 +30,6 @@
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.DockUpdaterFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -86,7 +85,7 @@
public int getAvailabilityStatus() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/core/BasePreferenceController.java b/src/com/android/settings/core/BasePreferenceController.java
index 44305dd..c3eb672 100644
--- a/src/com/android/settings/core/BasePreferenceController.java
+++ b/src/com/android/settings/core/BasePreferenceController.java
@@ -49,8 +49,8 @@
* {@link #isSupported()}.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({AVAILABLE, DISABLED_UNSUPPORTED, DISABLED_FOR_USER, DISABLED_DEPENDENT_SETTING,
- UNAVAILABLE_UNKNOWN})
+ @IntDef({AVAILABLE, UNSUPPORTED_ON_DEVICE, DISABLED_FOR_USER, DISABLED_DEPENDENT_SETTING,
+ CONDITIONALLY_UNAVAILABLE})
public @interface AvailabilityStatus {
}
@@ -60,12 +60,20 @@
public static final int AVAILABLE = 0;
/**
- * The setting is not supported by the device.
+ * A generic catch for settings which are currently unavailable, but may become available in
+ * the future. You should use {@link #DISABLED_FOR_USER} or {@link #DISABLED_DEPENDENT_SETTING}
+ * if they describe the condition more accurately.
+ */
+ public static final int CONDITIONALLY_UNAVAILABLE = 1;
+
+ /**
+ * The setting is not, and will not supported by this device.
* <p>
* There is no guarantee that the setting page exists, and any links to the Setting should take
* you to the home page of Settings.
*/
- public static final int DISABLED_UNSUPPORTED = 1;
+ public static final int UNSUPPORTED_ON_DEVICE = 2;
+
/**
* The setting cannot be changed by the current user.
@@ -73,7 +81,7 @@
* Links to the Setting should take you to the page of the Setting, even if it cannot be
* changed.
*/
- public static final int DISABLED_FOR_USER = 2;
+ public static final int DISABLED_FOR_USER = 3;
/**
* The setting has a dependency in the Settings App which is currently blocking access.
@@ -90,15 +98,8 @@
* Links to the Setting should take you to the page of the Setting, even if it cannot be
* changed.
*/
- public static final int DISABLED_DEPENDENT_SETTING = 3;
+ public static final int DISABLED_DEPENDENT_SETTING = 4;
- /**
- * A catch-all case for internal errors and inexplicable unavailability.
- * <p>
- * There is no guarantee that the setting page exists, and any links to the Setting should take
- * you to the home page of Settings.
- */
- public static final int UNAVAILABLE_UNKNOWN = 4;
protected final String mPreferenceKey;
@@ -181,8 +182,8 @@
@Override
public final boolean isAvailable() {
final int availabilityStatus = getAvailabilityStatus();
- return (availabilityStatus == AVAILABLE) ||
- (availabilityStatus == DISABLED_DEPENDENT_SETTING);
+ return (availabilityStatus == AVAILABLE
+ || availabilityStatus == DISABLED_DEPENDENT_SETTING);
}
/**
@@ -193,7 +194,7 @@
* Note that a return value of {@code true} does not mean that the setting is available.
*/
public final boolean isSupported() {
- return getAvailabilityStatus() != DISABLED_UNSUPPORTED;
+ return getAvailabilityStatus() != UNSUPPORTED_ON_DEVICE;
}
/**
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
index 58faac2..0767f7a 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
@@ -28,7 +28,6 @@
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.text.TextUtils;
-import android.text.format.Formatter;
import android.util.Log;
import android.util.RecurrenceRule;
@@ -182,7 +181,7 @@
@Override
public int getAvailabilityStatus() {
return DataUsageUtils.hasSim(mActivity)
- || DataUsageUtils.hasWifiRadio(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ || DataUsageUtils.hasWifiRadio(mContext) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
index a6d5363..cb04ed4 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
@@ -50,7 +50,7 @@
if (mConfig == null) {
mConfig = new AmbientDisplayConfiguration(mContext);
}
- return isAvailable(mConfig) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isAvailable(mConfig) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
index 15eb8b3..a44b294 100644
--- a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
@@ -86,7 +86,7 @@
if (mConfig == null) {
mConfig = new AmbientDisplayConfiguration(mContext);
}
- return mConfig.pulseOnNotificationAvailable() ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return mConfig.pulseOnNotificationAvailable() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index 28f9260..564e27a 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -57,7 +57,7 @@
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java
index 596e2c6..6580b03 100644
--- a/src/com/android/settings/display/AutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/AutoRotatePreferenceController.java
@@ -71,7 +71,7 @@
@Override
public int getAvailabilityStatus() {
return RotationPolicy.isRotationLockToggleVisible(mContext)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
index 9634739..7f50d0a 100644
--- a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
@@ -50,7 +50,7 @@
@Override
public int getAvailabilityStatus() {
- return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java
index e7b7de2..4ae15f2 100644
--- a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java
@@ -37,7 +37,7 @@
@Override
public int getAvailabilityStatus() {
- return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/NightDisplayCustomEndTimePreferenceController.java b/src/com/android/settings/display/NightDisplayCustomEndTimePreferenceController.java
index 524e7db..f76e730 100644
--- a/src/com/android/settings/display/NightDisplayCustomEndTimePreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayCustomEndTimePreferenceController.java
@@ -35,7 +35,7 @@
@Override
public int getAvailabilityStatus() {
- return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/NightDisplayCustomStartTimePreferenceController.java b/src/com/android/settings/display/NightDisplayCustomStartTimePreferenceController.java
index 4dda8f4..da54d87 100644
--- a/src/com/android/settings/display/NightDisplayCustomStartTimePreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayCustomStartTimePreferenceController.java
@@ -35,7 +35,7 @@
@Override
public int getAvailabilityStatus() {
- return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/NightDisplayFooterPreferenceController.java b/src/com/android/settings/display/NightDisplayFooterPreferenceController.java
index 228d271..15dd501 100644
--- a/src/com/android/settings/display/NightDisplayFooterPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayFooterPreferenceController.java
@@ -31,7 +31,7 @@
@Override
public int getAvailabilityStatus() {
- return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java b/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java
index b039644..ec7e577 100644
--- a/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java
@@ -35,7 +35,7 @@
@Override
public int getAvailabilityStatus() {
if (!ColorDisplayController.isAvailable(mContext)) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
} else if (!mController.isActivated()) {
return DISABLED_DEPENDENT_SETTING;
}
diff --git a/src/com/android/settings/fingerprint/FingerprintStatusPreferenceController.java b/src/com/android/settings/fingerprint/FingerprintStatusPreferenceController.java
index 19eb4bb..91af1ce 100644
--- a/src/com/android/settings/fingerprint/FingerprintStatusPreferenceController.java
+++ b/src/com/android/settings/fingerprint/FingerprintStatusPreferenceController.java
@@ -60,7 +60,7 @@
@Override
public int getAvailabilityStatus() {
if (mFingerprintManager == null || !mFingerprintManager.isHardwareDetected()) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
if (isUserSupported()) {
return AVAILABLE;
diff --git a/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceController.java b/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceController.java
index e8e5ad9..d7bfbc7 100644
--- a/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceController.java
@@ -42,7 +42,7 @@
@Override
public int getAvailabilityStatus() {
return mPowerUsageFeatureProvider.isSmartBatterySupported()
- ? DISABLED_UNSUPPORTED
+ ? UNSUPPORTED_ON_DEVICE
: AVAILABLE;
}
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 639c1fb..f78d236 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -512,37 +512,6 @@
}
/**
- * Check if the app represented by {@code uid} has battery usage more than {@code threshold}
- *
- * @param batteryStatsHelper used to check the battery usage
- * @param userManager used to init the {@code batteryStatsHelper}
- * @param uid represent the app
- * @param threshold battery percentage threshold(e.g. 10 means 10% battery usage )
- * @return {@code true} if battery drain is more than the threshold
- */
- public boolean isAppHeavilyUsed(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
- int uid, int threshold) {
- initBatteryStatsHelper(batteryStatsHelper, null /* bundle */, userManager);
- final int dischargeAmount = batteryStatsHelper.getStats().getDischargeAmount(
- BatteryStats.STATS_SINCE_CHARGED);
- List<BatterySipper> batterySippers = batteryStatsHelper.getUsageList();
- final double hiddenAmount = removeHiddenBatterySippers(batterySippers);
-
- for (int i = 0, size = batterySippers.size(); i < size; i++) {
- final BatterySipper batterySipper = batterySippers.get(i);
- if (batterySipper.getUid() == uid) {
- final int percent = (int) calculateBatteryPercent(
- batterySipper.totalPowerMah, batteryStatsHelper.getTotalPower(),
- hiddenAmount,
- dischargeAmount);
- return percent >= threshold;
- }
- }
-
- return false;
- }
-
- /**
* Return {@code true} if we should hide anomaly app represented by {@code uid}
*/
public boolean shouldHideAnomaly(PowerWhitelistBackend powerWhitelistBackend, int uid) {
diff --git a/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
index e222b91..3e80c35 100644
--- a/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
@@ -45,7 +45,7 @@
public int getAvailabilityStatus() {
return mPowerUsageFeatureProvider.isSmartBatterySupported()
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
index bbeb435..2fac9b6 100644
--- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
@@ -143,7 +143,6 @@
StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES);
final AnomalyInfo anomalyInfo = new AnomalyInfo(
!ArrayUtils.isEmpty(cookies) ? cookies.get(0) : "");
- final PackageManager packageManager = context.getPackageManager();
Log.i(TAG, "Extra stats value: " + intentDimsValue.toString());
try {
@@ -158,9 +157,7 @@
final boolean anomalyDetected;
if (isExcessiveBackgroundAnomaly(anomalyInfo)) {
- anomalyDetected = batteryUtils.isPreOApp(packageName)
- && batteryUtils.isAppHeavilyUsed(batteryStatsHelper, userManager, uid,
- policy.excessiveBgDrainPercentage);
+ anomalyDetected = batteryUtils.isPreOApp(packageName);
} else {
anomalyDetected = true;
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
index b9194b4..fc2bbdf 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
@@ -67,7 +67,7 @@
final BatteryInfo batteryInfo = mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG);
final Context context = getContext();
- tips.add(new LowBatteryDetector(policy, batteryInfo).detect());
+ tips.add(new LowBatteryDetector(context, policy, batteryInfo).detect());
tips.add(new HighUsageDetector(context, policy, mBatteryStatsHelper,
batteryInfo.discharging).detect());
tips.add(new SmartBatteryDetector(policy, context.getContentResolver()).detect());
@@ -87,7 +87,8 @@
final List<BatteryTip> tips = new ArrayList<>();
tips.add(new SummaryTip(BatteryTip.StateType.NEW,
Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN));
- tips.add(new LowBatteryTip(BatteryTip.StateType.NEW));
+ tips.add(new LowBatteryTip(BatteryTip.StateType.NEW, false /* powerSaveModeOn */,
+ "Fake data"));
return tips;
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
index 5520bf3..1c7c760 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
@@ -50,6 +50,7 @@
private static final String KEY_TEST_BATTERY_SAVER_TIP = "test_battery_saver_tip";
private static final String KEY_TEST_HIGH_USAGE_TIP = "test_high_usage_tip";
private static final String KEY_TEST_SMART_BATTERY_TIP = "test_smart_battery_tip";
+ private static final String KEY_TEST_LOW_BATTERY_TIP = "test_low_battery_tip";
/**
* {@code true} if general battery tip is enabled
@@ -192,6 +193,14 @@
*/
public final boolean testSmartBatteryTip;
+ /**
+ * {@code true} if we want to test low battery tip.
+ *
+ * @see Settings.Global#BATTERY_TIP_CONSTANTS
+ * @see #KEY_TEST_LOW_BATTERY_TIP
+ */
+ public final boolean testLowBatteryTip;
+
private final KeyValueListParser mParser;
public BatteryTipPolicy(Context context) {
@@ -222,13 +231,14 @@
reducedBatteryEnabled = mParser.getBoolean(KEY_REDUCED_BATTERY_ENABLED, false);
reducedBatteryPercent = mParser.getInt(KEY_REDUCED_BATTERY_PERCENT, 50);
lowBatteryEnabled = mParser.getBoolean(KEY_LOW_BATTERY_ENABLED, false);
- lowBatteryHour = mParser.getInt(KEY_LOW_BATTERY_HOUR, 16);
+ lowBatteryHour = mParser.getInt(KEY_LOW_BATTERY_HOUR, 3);
dataHistoryRetainDay = mParser.getInt(KEY_DATA_HISTORY_RETAIN_DAY, 30);
excessiveBgDrainPercentage = mParser.getInt(KEY_EXCESSIVE_BG_DRAIN_PERCENTAGE, 10);
testBatterySaverTip = mParser.getBoolean(KEY_TEST_BATTERY_SAVER_TIP, false);
testHighUsageTip = mParser.getBoolean(KEY_TEST_HIGH_USAGE_TIP, false);
testSmartBatteryTip = mParser.getBoolean(KEY_TEST_SMART_BATTERY_TIP, false);
+ testLowBatteryTip = mParser.getBoolean(KEY_TEST_LOW_BATTERY_TIP, false);
}
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
index 2a6302e..c3f9b07 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
@@ -16,31 +16,52 @@
package com.android.settings.fuelgauge.batterytip.detectors;
-import android.text.format.DateUtils;
+import android.content.Context;
+import android.os.PowerManager;
import com.android.settings.fuelgauge.BatteryInfo;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip;
+import java.util.concurrent.TimeUnit;
+
/**
* Detect whether the battery is too low
*/
public class LowBatteryDetector implements BatteryTipDetector {
private BatteryInfo mBatteryInfo;
private BatteryTipPolicy mPolicy;
+ private PowerManager mPowerManager;
+ private int mWarningLevel;
- public LowBatteryDetector(BatteryTipPolicy policy, BatteryInfo batteryInfo) {
+ public LowBatteryDetector(Context context, BatteryTipPolicy policy, BatteryInfo batteryInfo) {
mPolicy = policy;
mBatteryInfo = batteryInfo;
+ mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mWarningLevel = context.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryWarningLevel);
}
@Override
public BatteryTip detect() {
- // Show it if battery life is less than mPolicy.lowBatteryHour
- final boolean isShown = mPolicy.lowBatteryEnabled && mBatteryInfo.discharging
- && mBatteryInfo.remainingTimeUs < mPolicy.lowBatteryHour * DateUtils.HOUR_IN_MILLIS;
+ final boolean powerSaveModeOn = mPowerManager.isPowerSaveMode();
+ final boolean lowBattery = mBatteryInfo.batteryLevel <= mWarningLevel
+ || (mBatteryInfo.discharging
+ && mBatteryInfo.remainingTimeUs < TimeUnit.HOURS.toMicros(mPolicy.lowBatteryHour));
+
+ int state = BatteryTip.StateType.INVISIBLE;
+ if (mPolicy.lowBatteryEnabled) {
+ if (powerSaveModeOn) {
+ // Show it is handled if battery saver is on
+ state = BatteryTip.StateType.HANDLED;
+ } else if (mPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery)) {
+ // Show it is new if in test or in discharging low battery state
+ state = BatteryTip.StateType.NEW;
+ }
+ }
+
return new LowBatteryTip(
- isShown ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE);
+ state, powerSaveModeOn, mBatteryInfo.remainingLabel);
}
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
index f02dd72..2afdc81 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
@@ -74,10 +74,10 @@
TIP_ORDER.append(TipType.APP_RESTRICTION, 0);
TIP_ORDER.append(TipType.BATTERY_SAVER, 1);
TIP_ORDER.append(TipType.HIGH_DEVICE_USAGE, 2);
- TIP_ORDER.append(TipType.SUMMARY, 3);
- TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 4);
- TIP_ORDER.append(TipType.REDUCED_BATTERY, 5);
- TIP_ORDER.append(TipType.LOW_BATTERY, 6);
+ TIP_ORDER.append(TipType.LOW_BATTERY, 3);
+ TIP_ORDER.append(TipType.SUMMARY, 4);
+ TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 5);
+ TIP_ORDER.append(TipType.REDUCED_BATTERY, 6);
TIP_ORDER.append(TipType.REMOVE_APP_RESTRICTION, 7);
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
index 86237dd..b48a7dd 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
@@ -25,36 +25,32 @@
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/**
- * Tip to show current battery life is short
+ * Tip to show current battery level is low or remaining time is less than a certain period
*/
-public class LowBatteryTip extends BatteryTip {
+public class LowBatteryTip extends EarlyWarningTip {
+ private CharSequence mSummary;
- public LowBatteryTip(@StateType int state) {
- super(TipType.LOW_BATTERY, state, false /* showDialog */);
+ public LowBatteryTip(@StateType int state, boolean powerSaveModeOn, CharSequence summary) {
+ super(state, powerSaveModeOn);
+ mType = TipType.LOW_BATTERY;
+ mSummary = summary;
}
- private LowBatteryTip(Parcel in) {
+ public LowBatteryTip(Parcel in) {
super(in);
- }
-
- @Override
- public CharSequence getTitle(Context context) {
- return context.getString(R.string.battery_tip_low_battery_title);
+ mSummary = in.readCharSequence();
}
@Override
public CharSequence getSummary(Context context) {
- return context.getString(R.string.battery_tip_low_battery_summary);
+ return mState == StateType.HANDLED ? context.getString(
+ R.string.battery_tip_early_heads_up_done_summary) : mSummary;
}
@Override
- public int getIconId() {
- return R.drawable.ic_perm_device_information_red_24dp;
- }
-
- @Override
- public void updateState(BatteryTip tip) {
- mState = tip.mState;
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeCharSequence(mSummary);
}
@Override
diff --git a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
index fd94f9f..8a8e099 100644
--- a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
+++ b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
@@ -63,7 +63,7 @@
public int getAvailabilityStatus() {
final boolean isAvailable = mAssistOnly ? mFeatureProvider.isSupported(mContext)
: mFeatureProvider.isSensorAvailable(mContext);
- return isAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isAvailable ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
index aebda18..c400cbd 100644
--- a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
@@ -58,7 +58,7 @@
@Override
public int getAvailabilityStatus() {
- return isGestureAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
index 00fb956..94ef978 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
@@ -74,7 +74,7 @@
if (mAmbientConfig == null) {
mAmbientConfig = new AmbientDisplayConfiguration(mContext);
}
- return mAmbientConfig.pulseOnDoubleTapAvailable() ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return mAmbientConfig.pulseOnDoubleTapAvailable() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/DoubleTwistPreferenceController.java b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
index f819508..2dd8635 100644
--- a/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
@@ -68,7 +68,7 @@
@Override
public int getAvailabilityStatus() {
- return isGestureAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
index 1eb188a..0e00abb 100644
--- a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
+++ b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
@@ -51,7 +51,7 @@
for (AbstractPreferenceController controller : mGestureControllers) {
isAvailable = isAvailable || controller.isAvailable();
}
- return isAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isAvailable ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
/**
diff --git a/src/com/android/settings/gestures/PickupGesturePreferenceController.java b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
index 46318f5..d50df19 100644
--- a/src/com/android/settings/gestures/PickupGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
@@ -68,7 +68,7 @@
if (mAmbientConfig == null) {
mAmbientConfig = new AmbientDisplayConfiguration(mContext);
}
- return mAmbientConfig.pulseOnPickupAvailable() ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return mAmbientConfig.pulseOnPickupAvailable() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/PreventRingingPreferenceController.java b/src/com/android/settings/gestures/PreventRingingPreferenceController.java
index 493755f..66aef60 100644
--- a/src/com/android/settings/gestures/PreventRingingPreferenceController.java
+++ b/src/com/android/settings/gestures/PreventRingingPreferenceController.java
@@ -61,7 +61,7 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
index d755d72..bb6a26d 100644
--- a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
@@ -56,7 +56,7 @@
@Override
public int getAvailabilityStatus() {
- return isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/SwipeUpPreferenceController.java b/src/com/android/settings/gestures/SwipeUpPreferenceController.java
index c3abd46..27c7241 100644
--- a/src/com/android/settings/gestures/SwipeUpPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeUpPreferenceController.java
@@ -19,17 +19,12 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
import com.android.settings.R;
-import com.android.settings.Utils;
public class SwipeUpPreferenceController extends GesturePreferenceController {
@@ -46,6 +41,10 @@
}
static boolean isGestureAvailable(Context context) {
+ if (!context.getResources().getBoolean(R.bool.config_swipe_up_gesture_setting_available)) {
+ return false;
+ }
+
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
context.getString(com.android.internal.R.string.config_recentsComponentName));
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
@@ -59,7 +58,7 @@
@Override
public int getAvailabilityStatus() {
- return isGestureAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -81,8 +80,10 @@
@Override
public boolean isChecked() {
+ final int defaultValue = mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default) ? ON : OFF;
final int swipeUpEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, OFF);
+ Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, defaultValue);
return swipeUpEnabled != OFF;
}
}
diff --git a/src/com/android/settings/inputmethod/GameControllerPreferenceController.java b/src/com/android/settings/inputmethod/GameControllerPreferenceController.java
index 85aef63..4fc29ec 100644
--- a/src/com/android/settings/inputmethod/GameControllerPreferenceController.java
+++ b/src/com/android/settings/inputmethod/GameControllerPreferenceController.java
@@ -64,7 +64,7 @@
public int getAvailabilityStatus() {
// If device explicitly wants to hide this, return early.
if (!mContext.getResources().getBoolean(R.bool.config_show_vibrate_input_devices)) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
final int[] devices = mIm.getInputDeviceIds();
@@ -74,7 +74,7 @@
return AVAILABLE;
}
}
- return DISABLED_UNSUPPORTED;
+ return CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/language/PointerSpeedController.java b/src/com/android/settings/language/PointerSpeedController.java
index 857751c..c7275e1 100644
--- a/src/com/android/settings/language/PointerSpeedController.java
+++ b/src/com/android/settings/language/PointerSpeedController.java
@@ -36,6 +36,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_pointer_speed)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
diff --git a/src/com/android/settings/location/LocationScanningPreferenceController.java b/src/com/android/settings/location/LocationScanningPreferenceController.java
index ec487e4..6c63010 100644
--- a/src/com/android/settings/location/LocationScanningPreferenceController.java
+++ b/src/com/android/settings/location/LocationScanningPreferenceController.java
@@ -36,6 +36,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_location_scanning)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index 56c305d..b6246e3 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -93,7 +93,7 @@
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {
- return isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/notification/AlarmVolumePreferenceController.java b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
index 0900e3c..3c238aa 100644
--- a/src/com/android/settings/notification/AlarmVolumePreferenceController.java
+++ b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.media.AudioManager;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
public class AlarmVolumePreferenceController extends
@@ -34,7 +33,7 @@
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_alarm_volume)
- && !mHelper.isSingleVolume() ? AVAILABLE : DISABLED_UNSUPPORTED;
+ && !mHelper.isSingleVolume() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/notification/BadgingNotificationPreferenceController.java b/src/com/android/settings/notification/BadgingNotificationPreferenceController.java
index 37e3db0..260a415 100644
--- a/src/com/android/settings/notification/BadgingNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/BadgingNotificationPreferenceController.java
@@ -84,7 +84,7 @@
public int getAvailabilityStatus() {
return mContext.getResources()
.getBoolean(com.android.internal.R.bool.config_notificationBadging)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/notification/MediaVolumePreferenceController.java b/src/com/android/settings/notification/MediaVolumePreferenceController.java
index 8f0a7f9..f3bffe0 100644
--- a/src/com/android/settings/notification/MediaVolumePreferenceController.java
+++ b/src/com/android/settings/notification/MediaVolumePreferenceController.java
@@ -18,9 +18,8 @@
import android.content.Context;
import android.media.AudioManager;
-import com.android.settings.notification.VolumeSeekBarPreference.Callback;
+
import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.Lifecycle;
public class MediaVolumePreferenceController extends
VolumeSeekBarPreferenceController {
@@ -35,7 +34,7 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_media_volume)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
index 8e7171d..c3c8793 100644
--- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java
+++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.media.AudioManager;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -36,7 +35,7 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_notification_volume)
&& !Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume()
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/notification/RingVolumePreferenceController.java b/src/com/android/settings/notification/RingVolumePreferenceController.java
index e74b110..e328cd2 100644
--- a/src/com/android/settings/notification/RingVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RingVolumePreferenceController.java
@@ -30,7 +30,6 @@
import android.os.Message;
import android.os.Vibrator;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -85,7 +84,7 @@
@Override
public int getAvailabilityStatus() {
return Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume()
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java
index 3c6a026..d579256 100644
--- a/src/com/android/settings/notification/ZenModeBackend.java
+++ b/src/com/android/settings/notification/ZenModeBackend.java
@@ -16,6 +16,9 @@
package com.android.settings.notification;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
+
import android.app.ActivityManager;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
@@ -146,19 +149,24 @@
protected void savePolicy(int priorityCategories, int priorityCallSenders,
int priorityMessageSenders, int suppressedVisualEffects) {
mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders,
- priorityMessageSenders,
- suppressedVisualEffects);
+ priorityMessageSenders, suppressedVisualEffects);
mNotificationManager.setNotificationPolicy(mPolicy);
}
- protected int getNewSuppressedEffects(boolean suppress, int effectType) {
+ private int getNewSuppressedEffects(boolean suppress, int effectType) {
int effects = mPolicy.suppressedVisualEffects;
+
if (suppress) {
effects |= effectType;
} else {
effects &= ~effectType;
}
- return effects;
+
+ return clearDeprecatedEffects(effects);
+ }
+
+ private int clearDeprecatedEffects(int effects) {
+ return effects & ~(SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
}
protected boolean isEffectAllowed(int effect) {
diff --git a/src/com/android/settings/notification/ZenModeCallsSettings.java b/src/com/android/settings/notification/ZenModeCallsSettings.java
index 20396b5..cd56d7b 100644
--- a/src/com/android/settings/notification/ZenModeCallsSettings.java
+++ b/src/com/android/settings/notification/ZenModeCallsSettings.java
@@ -16,6 +16,8 @@
package com.android.settings.notification;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+
import android.content.Context;
import android.provider.SearchIndexableResource;
@@ -40,8 +42,8 @@
Lifecycle lifecycle) {
List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new ZenModeCallsPreferenceController(context, lifecycle));
- // TODO: is a controller needed for a pref that just launches an external activity?
- // or can the contacts app insert this setting themselves?
+ controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
+ PRIORITY_CATEGORY_CALLS));
controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
context.getResources().getInteger(com.android.internal.R.integer
.config_zen_repeat_callers_threshold)));
diff --git a/src/com/android/settings/notification/ZenModeMsgEventReminderSettings.java b/src/com/android/settings/notification/ZenModeMsgEventReminderSettings.java
index c2508e3..95b9f7e 100644
--- a/src/com/android/settings/notification/ZenModeMsgEventReminderSettings.java
+++ b/src/com/android/settings/notification/ZenModeMsgEventReminderSettings.java
@@ -16,6 +16,8 @@
package com.android.settings.notification;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+
import android.content.Context;
import android.provider.SearchIndexableResource;
@@ -42,6 +44,8 @@
controllers.add(new ZenModeEventsPreferenceController(context, lifecycle));
controllers.add(new ZenModeRemindersPreferenceController(context, lifecycle));
controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
+ PRIORITY_CATEGORY_MESSAGES));
controllers.add(new ZenModeBehaviorFooterPreferenceController(context, lifecycle,
R.string.zen_msg_event_reminder_footer));
return controllers;
diff --git a/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java b/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java
index 307dfcf..14b82f5 100644
--- a/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java
+++ b/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java
@@ -68,7 +68,6 @@
custom.displayPreference(getPreferenceScreen());
if (mShowMenuSelected) {
- custom.select();
metrics.action(mContext, ACTION_ZEN_SHOW_CUSTOM, true);
} else {
metrics.action(mContext, ACTION_ZEN_SHOW_CUSTOM, false);
diff --git a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
new file mode 100644
index 0000000..1b8a3d5
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2018 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.notification;
+
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.icu.text.ListFormatter;
+import android.provider.Contacts;
+import android.provider.ContactsContract;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenModeStarredContactsPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceClickListener {
+
+ protected static final String KEY = "zen_mode_starred_contacts";
+ private Preference mPreference;
+ private final int mPriorityCategory;
+ private final PackageManager mPackageManager;
+
+ @VisibleForTesting
+ Intent mStarredContactsIntent;
+ @VisibleForTesting
+ Intent mFallbackIntent;
+
+ public ZenModeStarredContactsPreferenceController(Context context, Lifecycle lifecycle, int
+ priorityCategory) {
+ super(context, KEY, lifecycle);
+ mPriorityCategory = priorityCategory;
+ mPackageManager = mContext.getPackageManager();
+
+ mStarredContactsIntent = new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
+
+ mFallbackIntent = new Intent(Intent.ACTION_MAIN);
+ mFallbackIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(KEY);
+ mPreference.setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (mPriorityCategory == PRIORITY_CATEGORY_CALLS) {
+ return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CALLS)
+ && mBackend.getPriorityCallSenders() == PRIORITY_SENDERS_STARRED
+ && isIntentValid();
+ } else if (mPriorityCategory == PRIORITY_CATEGORY_MESSAGES) {
+ return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_MESSAGES)
+ && mBackend.getPriorityMessageSenders() == PRIORITY_SENDERS_STARRED
+ && isIntentValid();
+ } else {
+ // invalid category
+ return false;
+ }
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ List<String> starredContacts = getStarredContacts();
+ int numStarredContacts = starredContacts.size();
+
+ List<String> displayContacts = new ArrayList<>();
+
+ if (numStarredContacts == 0) {
+ displayContacts.add(mContext.getString(R.string.zen_mode_from_none));
+ } else {
+ for (int i = 0; i < 2 && i < numStarredContacts; i++) {
+ displayContacts.add(starredContacts.get(i));
+ }
+
+ if (numStarredContacts == 3) {
+ displayContacts.add(starredContacts.get(2));
+ } else if (numStarredContacts > 2) {
+ displayContacts.add(mContext.getResources().getQuantityString(
+ R.plurals.zen_mode_starred_contacts_summary_additional_contacts,
+ numStarredContacts - 2, numStarredContacts - 2));
+ }
+ }
+
+ mPreference.setSummary(ListFormatter.getInstance().format(displayContacts));
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ if (mStarredContactsIntent.resolveActivity(mPackageManager) != null) {
+ mContext.startActivity(mStarredContactsIntent);
+ } else {
+ mContext.startActivity(mFallbackIntent);
+ }
+ return true;
+ }
+
+ private List<String> getStarredContacts() {
+ List<String> starredContacts = new ArrayList<>();
+
+ Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
+ new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
+ ContactsContract.Data.STARRED + "=1", null,
+ ContactsContract.Data.TIMES_CONTACTED);
+
+ if (cursor.moveToFirst()) {
+ do {
+ starredContacts.add(cursor.getString(0));
+ } while (cursor.moveToNext());
+ }
+ return starredContacts;
+ }
+
+ private boolean isIntentValid() {
+ return mStarredContactsIntent.resolveActivity(mPackageManager) != null
+ || mFallbackIntent.resolveActivity(mPackageManager) != null;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceController.java b/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceController.java
index fd235e6..83ab037 100644
--- a/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceController.java
@@ -19,7 +19,6 @@
import android.app.NotificationManager.Policy;
import android.content.Context;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -57,15 +56,11 @@
pref.setChecked(areCustomOptionsSelected());
pref.setOnGearClickListener(p -> {
- new SubSettingLauncher(mContext)
- .setDestination(ZenModeBlockedEffectsSettings.class.getName())
- .setTitle(R.string.zen_mode_what_to_block_title)
- .setSourceMetricsCategory(MetricsProto.MetricsEvent.SETTINGS_ZEN_NOTIFICATIONS)
- .launch();
+ launchCustomSettings();
});
pref.setOnRadioButtonClickListener(p -> {
- select();
+ launchCustomSettings();
});
}
@@ -84,9 +79,14 @@
protected void select() {
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_ZEN_CUSTOM, true);
- mBackend.savePolicy(mBackend.mPolicy.priorityCategories,
- mBackend.mPolicy.priorityCallSenders,
- mBackend.mPolicy.priorityMessageSenders,
- INTERRUPTIVE_EFFECTS);
+ }
+
+ private void launchCustomSettings() {
+ select();
+ new SubSettingLauncher(mContext)
+ .setDestination(ZenModeBlockedEffectsSettings.class.getName())
+ .setTitle(R.string.zen_mode_what_to_block_title)
+ .setSourceMetricsCategory(MetricsProto.MetricsEvent.SETTINGS_ZEN_NOTIFICATIONS)
+ .launch();
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/print/PrintSettingPreferenceController.java b/src/com/android/settings/print/PrintSettingPreferenceController.java
index 14eb907..2307b2c 100644
--- a/src/com/android/settings/print/PrintSettingPreferenceController.java
+++ b/src/com/android/settings/print/PrintSettingPreferenceController.java
@@ -59,7 +59,7 @@
@Override
public int getAvailabilityStatus() {
return mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/security/EncryptionStatusPreferenceController.java b/src/com/android/settings/security/EncryptionStatusPreferenceController.java
index 8125599..0ecab36 100644
--- a/src/com/android/settings/security/EncryptionStatusPreferenceController.java
+++ b/src/com/android/settings/security/EncryptionStatusPreferenceController.java
@@ -44,7 +44,7 @@
if (TextUtils.equals(getPreferenceKey(), PREF_KEY_ENCRYPTION_DETAIL_PAGE) &&
!mContext.getResources().getBoolean(
R.bool.config_show_encryption_and_credentials_encryption_status)) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
return mUserManager.isAdminUser() ? AVAILABLE : DISABLED_FOR_USER;
diff --git a/src/com/android/settings/security/ScreenPinningPreferenceController.java b/src/com/android/settings/security/ScreenPinningPreferenceController.java
index a90746e..37a3f9c 100644
--- a/src/com/android/settings/security/ScreenPinningPreferenceController.java
+++ b/src/com/android/settings/security/ScreenPinningPreferenceController.java
@@ -33,7 +33,7 @@
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_screen_pinning_settings)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/security/ShowPasswordPreferenceController.java b/src/com/android/settings/security/ShowPasswordPreferenceController.java
index 82f1935..8672974 100644
--- a/src/com/android/settings/security/ShowPasswordPreferenceController.java
+++ b/src/com/android/settings/security/ShowPasswordPreferenceController.java
@@ -55,7 +55,7 @@
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_show_password)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
}
diff --git a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
index 3e39860..322682e 100644
--- a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
@@ -47,7 +47,7 @@
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_manage_trust_agents)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 55ad6b0..6d6c0ec 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -32,7 +32,6 @@
import android.support.annotation.VisibleForTesting;
import android.support.v4.graphics.drawable.IconCompat;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
@@ -42,10 +41,10 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
import androidx.slice.Slice;
import androidx.slice.SliceProvider;
@@ -117,6 +116,7 @@
@VisibleForTesting
Map<Uri, SliceData> mSliceWeakDataCache;
+ @VisibleForTesting
Map<Uri, SliceData> mSliceDataCache;
public SettingsSliceProvider() {
@@ -126,7 +126,7 @@
@Override
public boolean onCreateSliceProvider() {
mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(getContext());
- mSliceDataCache = new ArrayMap<>();
+ mSliceDataCache = new ConcurrentHashMap<>();
mSliceWeakDataCache = new WeakHashMap<>();
return true;
}
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index 0a4d51b..be2e8df 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -17,10 +17,10 @@
package com.android.settings.slices;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
-import static com.android.settings.core.BasePreferenceController.UNAVAILABLE_UNKNOWN;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
@@ -238,7 +238,7 @@
(TogglePreferenceController) controller;
final SliceAction sliceAction = getToggleAction(context, sliceData,
toggleController.isChecked());
- final List<String> keywords = buildSliceKeywords(sliceData.getKeywords());
+ final List<String> keywords = buildSliceKeywords(sliceData);
return new ListBuilder(context, sliceData.getUri(), SLICE_TTL_MILLIS)
.addRow(rowBuilder -> rowBuilder
@@ -256,7 +256,7 @@
final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
- final List<String> keywords = buildSliceKeywords(sliceData.getKeywords());
+ final List<String> keywords = buildSliceKeywords(sliceData);
return new ListBuilder(context, sliceData.getUri(), SLICE_TTL_MILLIS)
.addRow(rowBuilder -> rowBuilder
@@ -276,7 +276,7 @@
final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
final SliceAction primaryAction = new SliceAction(contentIntent, icon,
sliceData.getTitle());
- final List<String> keywords = buildSliceKeywords(sliceData.getKeywords());
+ final List<String> keywords = buildSliceKeywords(sliceData);
return new ListBuilder(context, sliceData.getUri(), SLICE_TTL_MILLIS)
.addInputRange(builder -> builder
@@ -324,25 +324,34 @@
|| TextUtils.equals(summary, doublePlaceHolder));
}
- private static List<String> buildSliceKeywords(String keywordString) {
- if (keywordString == null) {
- return new ArrayList<>();
+ private static List<String> buildSliceKeywords(SliceData data) {
+ final List<String> keywords = new ArrayList<>();
+
+ keywords.add(data.getTitle());
+
+ if (!TextUtils.equals(data.getTitle(), data.getScreenTitle())) {
+ keywords.add(data.getScreenTitle().toString());
}
- final String[] keywords = keywordString.split(",");
- return Arrays.asList(keywords);
+ final String keywordString = data.getKeywords();
+ if (keywordString != null) {
+ final String[] keywordArray = keywordString.split(",");
+ keywords.addAll(Arrays.asList(keywordArray));
+ }
+
+ return keywords;
}
private static Slice buildUnavailableSlice(Context context, SliceData data,
BasePreferenceController controller) {
final String title = data.getTitle();
- final List<String> keywords = buildSliceKeywords(data.getKeywords());
+ final List<String> keywords = buildSliceKeywords(data);
final String summary;
final SliceAction primaryAction;
final IconCompat icon = IconCompat.createWithResource(context, data.getIconResource());
switch (controller.getAvailabilityStatus()) {
- case DISABLED_UNSUPPORTED:
+ case UNSUPPORTED_ON_DEVICE:
summary = context.getString(R.string.unsupported_setting_summary);
primaryAction = new SliceAction(getSettingsIntent(context), icon, title);
break;
@@ -356,7 +365,7 @@
primaryAction = new SliceAction(getContentPendingIntent(context, data), icon,
title);
break;
- case UNAVAILABLE_UNKNOWN:
+ case CONDITIONALLY_UNAVAILABLE:
default:
summary = context.getString(R.string.unknown_unavailability_setting_summary);
primaryAction = new SliceAction(getSettingsIntent(context), icon, title);
diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java
index eb6a44f..7bd66ba 100644
--- a/src/com/android/settings/slices/SliceDataConverter.java
+++ b/src/com/android/settings/slices/SliceDataConverter.java
@@ -185,7 +185,6 @@
| MetadataFlag.FLAG_NEED_PREF_TITLE
| MetadataFlag.FLAG_NEED_PREF_ICON
| MetadataFlag.FLAG_NEED_PREF_SUMMARY
- | MetadataFlag.FLAG_NEED_KEYWORDS
| MetadataFlag.FLAG_NEED_PLATFORM_SLICE_FLAG);
for (Bundle bundle : metadata) {
@@ -198,7 +197,6 @@
final String key = bundle.getString(METADATA_KEY);
final String title = bundle.getString(METADATA_TITLE);
final String summary = bundle.getString(METADATA_SUMMARY);
- final String keywords = bundle.getString(METADATA_KEYWORDS);
final int iconResId = bundle.getInt(METADATA_ICON);
final int sliceType = SliceBuilderUtils.getSliceType(mContext, controllerClassName,
key);
@@ -210,7 +208,6 @@
.setSummary(summary)
.setIcon(iconResId)
.setScreenTitle(screenTitle)
- .setKeywords(keywords)
.setPreferenceControllerClassName(controllerClassName)
.setFragmentName(fragmentName)
.setSliceType(sliceType)
diff --git a/src/com/android/settings/sound/AudioSwitchPreferenceController.java b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
index 957cebf..81479c9 100644
--- a/src/com/android/settings/sound/AudioSwitchPreferenceController.java
+++ b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
@@ -16,8 +16,12 @@
package com.android.settings.sound;
-
import static android.media.AudioManager.STREAM_DEVICES_CHANGED_ACTION;
+import static android.media.AudioManager.STREAM_MUSIC;
+import static android.media.AudioManager.STREAM_VOICE_CALL;
+import static android.media.AudioSystem.DEVICE_OUT_ALL_A2DP;
+import static android.media.AudioSystem.DEVICE_OUT_ALL_SCO;
+import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY;
import android.bluetooth.BluetoothDevice;
@@ -38,19 +42,22 @@
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
-import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
+import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.HeadsetProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -65,12 +72,12 @@
private static final int INVALID_INDEX = -1;
+ protected final List<BluetoothDevice> mConnectedDevices;
protected final AudioManager mAudioManager;
protected final MediaRouter mMediaRouter;
protected final LocalBluetoothProfileManager mProfileManager;
protected int mSelectedIndex;
protected Preference mPreference;
- protected List<BluetoothDevice> mConnectedDevices;
private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback;
private final LocalBluetoothManager mLocalBluetoothManager;
@@ -89,6 +96,7 @@
mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback();
mReceiver = new WiredHeadsetBroadcastReceiver();
mMediaRouterCallback = new MediaRouterCallback();
+ mConnectedDevices = new ArrayList<>();
}
/**
@@ -98,7 +106,7 @@
@Override
public final int getAvailabilityStatus() {
return FeatureFlagUtils.isEnabled(mContext, FeatureFlags.AUDIO_SWITCHER_SETTINGS)
- ? AVAILABLE : DISABLED_UNSUPPORTED;
+ ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
@@ -195,12 +203,105 @@
}
protected boolean isStreamFromOutputDevice(int streamType, int device) {
- return mAudioManager.getDevicesForStream(streamType) == device;
+ return (device & mAudioManager.getDevicesForStream(streamType)) != 0;
+ }
+
+ /**
+ * get hands free profile(HFP) connected device
+ */
+ protected List<BluetoothDevice> getConnectedHfpDevices() {
+ final List<BluetoothDevice> connectedDevices = new ArrayList<>();
+ final HeadsetProfile hfpProfile = mProfileManager.getHeadsetProfile();
+ if (hfpProfile == null) {
+ return connectedDevices;
+ }
+ final List<BluetoothDevice> devices = hfpProfile.getConnectedDevices();
+ for (BluetoothDevice device : devices) {
+ if (device.isConnected()) {
+ connectedDevices.add(device);
+ }
+ }
+ return connectedDevices;
+ }
+
+ /**
+ * get A2dp connected device
+ */
+ protected List<BluetoothDevice> getConnectedA2dpDevices() {
+ final List<BluetoothDevice> connectedDevices = new ArrayList<>();
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ if (a2dpProfile == null) {
+ return connectedDevices;
+ }
+ final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices();
+ for (BluetoothDevice device : devices) {
+ if (device.isConnected()) {
+ connectedDevices.add(device);
+ }
+ }
+ return connectedDevices;
+ }
+
+ /**
+ * get hearing aid profile connected device, exclude other devices with same hiSyncId.
+ */
+ protected List<BluetoothDevice> getConnectedHearingAidDevices() {
+ final List<BluetoothDevice> connectedDevices = new ArrayList<>();
+ final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
+ if (hapProfile == null) {
+ return connectedDevices;
+ }
+ final List<Long> devicesHiSyncIds = new ArrayList<>();
+ final List<BluetoothDevice> devices = hapProfile.getConnectedDevices();
+ for (BluetoothDevice device : devices) {
+ final long hiSyncId = hapProfile.getHiSyncId(device);
+ // device with same hiSyncId should not be shown in the UI.
+ // So do not add it into connectedDevices.
+ if (!devicesHiSyncIds.contains(hiSyncId) && device.isConnected()) {
+ devicesHiSyncIds.add(hiSyncId);
+ connectedDevices.add(device);
+ }
+ }
+ return connectedDevices;
+ }
+
+ /**
+ * According to different stream and output device, find the active device from
+ * the corresponding profile. Hearing aid device could stream both STREAM_MUSIC
+ * and STREAM_VOICE_CALL.
+ *
+ * @param streamType the type of audio streams.
+ * @return the active device. Return null if the active device is current device
+ * or streamType is not STREAM_MUSIC or STREAM_VOICE_CALL.
+ */
+ protected BluetoothDevice findActiveDevice(int streamType) {
+ if (streamType != STREAM_MUSIC && streamType != STREAM_VOICE_CALL) {
+ return null;
+ }
+ if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_ALL_A2DP)) {
+ return mProfileManager.getA2dpProfile().getActiveDevice();
+ } else if (isStreamFromOutputDevice(STREAM_VOICE_CALL, DEVICE_OUT_ALL_SCO)) {
+ return mProfileManager.getHeadsetProfile().getActiveDevice();
+ } else if (isStreamFromOutputDevice(streamType, DEVICE_OUT_HEARING_AID)) {
+ // The first element is the left active device; the second element is
+ // the right active device. And they will have same hiSyncId. If either
+ // or both side is not active, it will be null on that position.
+ List<BluetoothDevice> activeDevices =
+ mProfileManager.getHearingAidProfile().getActiveDevices();
+ for (BluetoothDevice btDevice : activeDevices) {
+ if (btDevice != null && mConnectedDevices.contains(btDevice)) {
+ // also need to check mConnectedDevices, because one of
+ // the device(same hiSyncId) might not be shown in the UI.
+ return btDevice;
+ }
+ }
+ }
+ return null;
}
int getDefaultDeviceIndex() {
// Default device is after all connected devices.
- return ArrayUtils.size(mConnectedDevices);
+ return mConnectedDevices.size();
}
void setupPreferenceEntries(CharSequence[] mediaOutputs, CharSequence[] mediaValues,
@@ -261,7 +362,7 @@
mContext.unregisterReceiver(mReceiver);
}
- /** Callback for headset plugged and unplugged events. */
+ /** Notifications of audio device connection and disconnection events. */
private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback {
@Override
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
diff --git a/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java b/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java
index 6907a4a..2039913 100644
--- a/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java
+++ b/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java
@@ -16,6 +16,7 @@
package com.android.settings.sound;
+import static android.bluetooth.IBluetoothHearingAid.HI_SYNC_ID_INVALID;
import static android.media.AudioManager.STREAM_VOICE_CALL;
import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
@@ -25,12 +26,12 @@
import android.content.Context;
import android.support.v7.preference.Preference;
-import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
import com.android.settingslib.bluetooth.HeadsetProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
/**
- * This class allows switching between HFP-connected BT devices
+ * This class allows switching between HFP-connected & HAP-connected BT devices
* while in on-call state.
*/
public class HandsFreeProfileOutputPreferenceController extends
@@ -57,16 +58,11 @@
// Ongoing call status, list all the connected devices support hands free profile.
// Select current active device.
// Disable switch entry if there is no connected device.
- mConnectedDevices = null;
- BluetoothDevice activeDevice = null;
+ mConnectedDevices.clear();
+ mConnectedDevices.addAll(getConnectedHfpDevices());
+ mConnectedDevices.addAll(getConnectedHearingAidDevices());
- final HeadsetProfile headsetProfile = mProfileManager.getHeadsetProfile();
- if (headsetProfile != null) {
- mConnectedDevices = headsetProfile.getConnectedDevices();
- activeDevice = headsetProfile.getActiveDevice();
- }
-
- final int numDevices = ArrayUtils.size(mConnectedDevices);
+ final int numDevices = mConnectedDevices.size();
if (numDevices == 0) {
// No connected devices, disable switch entry.
mPreference.setVisible(false);
@@ -79,7 +75,7 @@
CharSequence[] mediaValues = new CharSequence[numDevices + 1];
// Setup devices entries, select active connected device
- setupPreferenceEntries(mediaOutputs, mediaValues, activeDevice);
+ setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_VOICE_CALL));
if (isStreamFromOutputDevice(STREAM_VOICE_CALL, DEVICE_OUT_USB_HEADSET)) {
// If wired headset is plugged in and active, select to default device.
@@ -92,8 +88,21 @@
@Override
public void setActiveBluetoothDevice(BluetoothDevice device) {
- if (Utils.isAudioModeOngoingCall(mContext)) {
- mProfileManager.getHeadsetProfile().setActiveDevice(device);
+ if (!Utils.isAudioModeOngoingCall(mContext)) {
+ return;
+ }
+ final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
+ final HeadsetProfile hfpProfile = mProfileManager.getHeadsetProfile();
+ if (hapProfile != null && hfpProfile != null && device == null) {
+ hfpProfile.setActiveDevice(null);
+ hapProfile.setActiveDevice(null);
+ return;
+ }
+ if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
+ hapProfile.setActiveDevice(device);
+ }
+ if (hfpProfile != null) {
+ hfpProfile.setActiveDevice(device);
}
}
}
diff --git a/src/com/android/settings/sound/MediaOutputPreferenceController.java b/src/com/android/settings/sound/MediaOutputPreferenceController.java
index d0677a7..79f3c9d 100644
--- a/src/com/android/settings/sound/MediaOutputPreferenceController.java
+++ b/src/com/android/settings/sound/MediaOutputPreferenceController.java
@@ -16,6 +16,7 @@
package com.android.settings.sound;
+import static android.bluetooth.IBluetoothHearingAid.HI_SYNC_ID_INVALID;
import static android.media.AudioManager.STREAM_MUSIC;
import static android.media.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
@@ -27,13 +28,12 @@
import android.media.AudioManager;
import android.support.v7.preference.Preference;
-import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
import com.android.settingslib.bluetooth.A2dpProfile;
-
+import com.android.settingslib.bluetooth.HearingAidProfile;
/**
- * This class which allows switching between a2dp-connected BT devices.
+ * This class which allows switching between A2dp-connected & HAP-connected BT devices.
* A few conditions will disable this switcher:
* - No available BT device(s)
* - Media stream captured by cast device
@@ -67,18 +67,14 @@
return;
}
+ mConnectedDevices.clear();
// Otherwise, list all of the A2DP connected device and display the active device.
- mConnectedDevices = null;
- BluetoothDevice activeDevice = null;
if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) {
- final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
- if (a2dpProfile != null) {
- mConnectedDevices = a2dpProfile.getConnectedDevices();
- activeDevice = a2dpProfile.getActiveDevice();
- }
+ mConnectedDevices.addAll(getConnectedA2dpDevices());
+ mConnectedDevices.addAll(getConnectedHearingAidDevices());
}
- final int numDevices = ArrayUtils.size(mConnectedDevices);
+ final int numDevices = mConnectedDevices.size();
if (numDevices == 0) {
// Disable switch entry if there is no connected devices.
mPreference.setVisible(false);
@@ -91,7 +87,7 @@
CharSequence[] mediaValues = new CharSequence[numDevices + 1];
// Setup devices entries, select active connected device
- setupPreferenceEntries(mediaOutputs, mediaValues, activeDevice);
+ setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_MUSIC));
if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_USB_HEADSET)) {
// If wired headset is plugged in and active, select to default device.
@@ -104,8 +100,21 @@
@Override
public void setActiveBluetoothDevice(BluetoothDevice device) {
- if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) {
- mProfileManager.getA2dpProfile().setActiveDevice(device);
+ if (mAudioManager.getMode() != AudioManager.MODE_NORMAL) {
+ return;
+ }
+ final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ if (hapProfile != null && a2dpProfile != null && device == null) {
+ hapProfile.setActiveDevice(null);
+ a2dpProfile.setActiveDevice(null);
+ return;
+ }
+ if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
+ hapProfile.setActiveDevice(device);
+ }
+ if (a2dpProfile != null) {
+ a2dpProfile.setActiveDevice(device);
}
}
}
diff --git a/src/com/android/settings/system/AdditionalSystemUpdatePreferenceController.java b/src/com/android/settings/system/AdditionalSystemUpdatePreferenceController.java
index 1fbf835..868f10f 100644
--- a/src/com/android/settings/system/AdditionalSystemUpdatePreferenceController.java
+++ b/src/com/android/settings/system/AdditionalSystemUpdatePreferenceController.java
@@ -32,6 +32,6 @@
return mContext.getResources().getBoolean(
com.android.settings.R.bool.config_additional_system_update_setting_enable)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/system/ResetPreferenceController.java b/src/com/android/settings/system/ResetPreferenceController.java
index 16f7ce3..ec0c27b 100644
--- a/src/com/android/settings/system/ResetPreferenceController.java
+++ b/src/com/android/settings/system/ResetPreferenceController.java
@@ -30,6 +30,6 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_reset_dashboard)
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
}
diff --git a/src/com/android/settings/system/SystemUpdatePreferenceController.java b/src/com/android/settings/system/SystemUpdatePreferenceController.java
index 80d4ecb..7bc76a2 100644
--- a/src/com/android/settings/system/SystemUpdatePreferenceController.java
+++ b/src/com/android/settings/system/SystemUpdatePreferenceController.java
@@ -55,7 +55,7 @@
return mContext.getResources().getBoolean(R.bool.config_show_system_update_settings)
&& mUm.isAdminUser()
? AVAILABLE
- : DISABLED_UNSUPPORTED;
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/widget/PreferenceCategoryController.java b/src/com/android/settings/widget/PreferenceCategoryController.java
index c6477f3..7b52be0 100644
--- a/src/com/android/settings/widget/PreferenceCategoryController.java
+++ b/src/com/android/settings/widget/PreferenceCategoryController.java
@@ -43,7 +43,7 @@
@Override
public int getAvailabilityStatus() {
if (mChildren == null || mChildren.isEmpty()) {
- return DISABLED_UNSUPPORTED;
+ return UNSUPPORTED_ON_DEVICE;
}
// Category is available if any child is available
for (AbstractPreferenceController controller : mChildren) {
@@ -51,7 +51,7 @@
return AVAILABLE;
}
}
- return DISABLED_UNSUPPORTED;
+ return CONDITIONALLY_UNAVAILABLE;
}
@Override
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index e995c31..79196f1 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -220,6 +220,7 @@
mMeteredSettingsSpinner = mView.findViewById(R.id.metered_settings);
mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings);
mHiddenSettingsSpinner.setOnItemSelectedListener(this);
+ mHiddenSettingsSpinner.setVisibility(View.GONE);
mHiddenSettingsSpinner.setEnabled(false);
mHiddenWarningView = mView.findViewById(R.id.hidden_settings_warning);
mHiddenWarningView.setVisibility(
@@ -240,6 +241,7 @@
showProxyFields();
mView.findViewById(R.id.wifi_advanced_toggle).setVisibility(View.VISIBLE);
// Hidden option can be changed only when the user adds a network manually.
+ mHiddenSettingsSpinner.setVisibility(View.VISIBLE);
mHiddenSettingsSpinner.setEnabled(true);
((CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox))
.setOnCheckedChangeListener(this);
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySlicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySlicePreferenceControllerTest.java
index fe6d1a3..8392412 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySlicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySlicePreferenceControllerTest.java
@@ -17,7 +17,7 @@
package com.android.settings.accessibility;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
@@ -30,7 +30,6 @@
import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
-import com.android.settings.accessibility.AccessibilitySlicePreferenceController;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.accessibility.AccessibilityUtils;
@@ -85,7 +84,7 @@
AccessibilitySlicePreferenceController controller =
new AccessibilitySlicePreferenceController(mContext, "fake_service/name");
- assertThat(controller.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java
index f87be57..72893b7 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceControllerTest.java
@@ -80,7 +80,7 @@
doReturn(false).when(mController).isBandwidthControlEnabled();
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java
index 64ad32b..5298fcd 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java
@@ -91,7 +91,7 @@
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
@@ -101,7 +101,7 @@
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
@@ -110,7 +110,7 @@
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
index e8e4032..97007f8 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
@@ -17,6 +17,7 @@
package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -84,7 +85,8 @@
mController.capable = false;
when(mUserManager.isManagedProfile()).thenReturn(false);
- assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ mController.UNSUPPORTED_ON_DEVICE);
}
@Test
@@ -110,9 +112,9 @@
public void handlePreferenceTreeClick_shouldStartDefaultAppSettings() {
mController.handlePreferenceTreeClick(mPreference);
- verify(mContext).startActivity(argThat(intent-> intent != null
+ verify(mContext).startActivity(argThat(intent -> intent != null
&& intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT).equals(
- DefaultAppSettings.class.getName())
+ DefaultAppSettings.class.getName())
&& intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY).equals("TestKey")));
}
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
index 0a54b82..e6cc831 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
@@ -71,7 +71,7 @@
mController.setPackageName(null);
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
@@ -79,7 +79,7 @@
mController.setPackageName(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
@@ -88,7 +88,7 @@
mController.setPackageName(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AddDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AddDevicePreferenceControllerTest.java
index 15872d1..ecf024b 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AddDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AddDevicePreferenceControllerTest.java
@@ -16,7 +16,7 @@
package com.android.settings.connecteddevice;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
@@ -121,7 +121,7 @@
public void addDevice_Availability_UnSupported() {
mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false);
assertThat(mAddDevicePreferenceController.getAvailabilityStatus())
- .isEqualTo(DISABLED_UNSUPPORTED);
+ .isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
index 93a0411..aeab451 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
@@ -16,7 +16,7 @@
package com.android.settings.connecteddevice;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -169,7 +169,7 @@
doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
assertThat(mAvailableMediaDeviceGroupController.getAvailabilityStatus()).isEqualTo(
- DISABLED_UNSUPPORTED);
+ UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java
index 12fca1e..83763bb 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/BluetoothOnWhileDrivingPreferenceControllerTest.java
@@ -54,7 +54,7 @@
@Test
public void getAvailabilityStatus_offWhenDisabled() {
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+ .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
index 3039895..718acb9 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
@@ -16,7 +16,7 @@
package com.android.settings.connecteddevice;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
@@ -39,7 +39,6 @@
import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
@@ -157,7 +156,7 @@
mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false);
assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
- DISABLED_UNSUPPORTED);
+ UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java
index 71c1010..2e40bf5 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java
@@ -16,7 +16,7 @@
package com.android.settings.connecteddevice;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
@@ -91,7 +91,7 @@
public void testGetAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
- DISABLED_UNSUPPORTED);
+ UNSUPPORTED_ON_DEVICE);
}
@Test
public void testGetAvailabilityStatus_BluetoothFeature_returnSupported() {
diff --git a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java
index 3074d9e..eec4e37 100644
--- a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java
@@ -16,10 +16,10 @@
package com.android.settings.core;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
-import static com.android.settings.core.BasePreferenceController.UNAVAILABLE_UNKNOWN;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
@@ -73,8 +73,16 @@
}
@Test
- public void isAvailable_availableStatusUnsupported_returnsFalse() {
- mPreferenceController.setAvailability(DISABLED_UNSUPPORTED);
+ public void isAvailable_availableStatusUnsupportedOnDevice_returnsFalse() {
+ mPreferenceController.setAvailability(UNSUPPORTED_ON_DEVICE);
+
+ assertThat(mPreferenceController.isAvailable()).isFalse();
+ }
+
+
+ @Test
+ public void isAvailable_availableStatusConditionallyUnavailable_returnsFalse() {
+ mPreferenceController.setAvailability(CONDITIONALLY_UNAVAILABLE);
assertThat(mPreferenceController.isAvailable()).isFalse();
}
@@ -94,13 +102,6 @@
}
@Test
- public void isAvailable_availableStatusUnavailable_returnsFalse() {
- mPreferenceController.setAvailability(UNAVAILABLE_UNKNOWN);
-
- assertThat(mPreferenceController.isAvailable()).isFalse();
- }
-
- @Test
public void isSupported_availableStatusAvailable_returnsTrue() {
mPreferenceController.setAvailability(AVAILABLE);
@@ -109,7 +110,7 @@
@Test
public void isSupported_availableStatusUnsupported_returnsFalse() {
- mPreferenceController.setAvailability(DISABLED_UNSUPPORTED);
+ mPreferenceController.setAvailability(UNSUPPORTED_ON_DEVICE);
assertThat(mPreferenceController.isSupported()).isFalse();
}
@@ -129,13 +130,6 @@
}
@Test
- public void isSupported_availableStatusUnavailable_returnsTrue() {
- mPreferenceController.setAvailability(UNAVAILABLE_UNKNOWN);
-
- assertThat(mPreferenceController.isSupported()).isTrue();
- }
-
- @Test
public void getSliceType_shouldReturnIntent() {
assertThat(mPreferenceController.getSliceType()).isEqualTo(SliceData.SliceType.INTENT);
}
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java
index 8682ac1..9e5a2b7 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java
@@ -18,7 +18,8 @@
import static android.net.ConnectivityManager.TYPE_WIFI;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
@@ -342,7 +343,7 @@
when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT);
when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false);
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
index e1c4b70..624b07f 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
@@ -77,7 +77,7 @@
when(mConfig.alwaysOnAvailableForUser(anyInt())).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
- AmbientDisplayAlwaysOnPreferenceController.DISABLED_UNSUPPORTED);
+ AmbientDisplayAlwaysOnPreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
index 5815f42..f0ce95f 100644
--- a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
@@ -104,7 +104,7 @@
@Test
public void testGetAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController
- .DISABLED_UNSUPPORTED);
+ .CONDITIONALLY_UNAVAILABLE);
enableAutoRotationPreference();
@@ -114,7 +114,7 @@
disableAutoRotationPreference();
assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController
- .DISABLED_UNSUPPORTED);
+ .CONDITIONALLY_UNAVAILABLE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintStatusPreferenceControllerTest.java
index 441f5b6..730b833 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintStatusPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintStatusPreferenceControllerTest.java
@@ -17,7 +17,7 @@
package com.android.settings.fingerprint;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
@@ -84,7 +84,7 @@
public void getAvailabilityStatus_noFingerprintManger_DISABLED() {
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceControllerTest.java
index 241f550..c66e6aa 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AutoRestrictionPreferenceControllerTest.java
@@ -91,7 +91,7 @@
doReturn(true).when(mFeatureFactory.powerUsageFeatureProvider).isSmartBatterySupported();
assertThat(mController.getAvailabilityStatus()).isEqualTo(
- BasePreferenceController.DISABLED_UNSUPPORTED);
+ BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index dc34016..5c2a1c7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -581,18 +581,6 @@
}
@Test
- public void testIsAppHeavilyUsed_usageMoreThanThreshold_returnTrue() {
- assertThat(mBatteryUtils.isAppHeavilyUsed(mBatteryStatsHelper, mUserManager, UID,
- 10 /* threshold */ )).isTrue();
- }
-
- @Test
- public void testIsAppHeavilyUsed_usageLessThanThreshold_returnFalse() {
- assertThat(mBatteryUtils.isAppHeavilyUsed(mBatteryStatsHelper, mUserManager, UID,
- DISCHARGE_AMOUNT /* threshold */ )).isFalse();
- }
-
- @Test
public void testShouldHideAnomaly_systemAppWithLauncher_returnTrue() {
final List<ResolveInfo> resolveInfos = new ArrayList<>();
final ResolveInfo resolveInfo = new ResolveInfo();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
index b91c5e1..717ba83 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
@@ -103,7 +103,7 @@
doReturn(false).when(mFeatureFactory.powerUsageFeatureProvider).isSmartBatterySupported();
assertThat(mController.getAvailabilityStatus()).isEqualTo(
- BasePreferenceController.DISABLED_UNSUPPORTED);
+ BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
private void putSmartBatteryValue(int value) {
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
index b50cc40..b0d6a7d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
@@ -48,9 +48,9 @@
BatteryTip.TipType.APP_RESTRICTION,
BatteryTip.TipType.BATTERY_SAVER,
BatteryTip.TipType.HIGH_DEVICE_USAGE,
+ BatteryTip.TipType.LOW_BATTERY,
BatteryTip.TipType.SUMMARY,
- BatteryTip.TipType.SMART_BATTERY_MANAGER,
- BatteryTip.TipType.LOW_BATTERY};
+ BatteryTip.TipType.SMART_BATTERY_MANAGER};
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private BatteryStatsHelper mBatteryStatsHelper;
@Mock
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
index 654b247..350326a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
@@ -48,7 +48,8 @@
+ ",excessive_bg_drain_percentage=25"
+ ",test_battery_saver_tip=true"
+ ",test_high_usage_tip=false"
- + ",test_smart_battery_tip=true";
+ + ",test_smart_battery_tip=true"
+ + ",test_low_battery_tip=true";
private Context mContext;
@Before
@@ -80,6 +81,7 @@
assertThat(batteryTipPolicy.testBatterySaverTip).isTrue();
assertThat(batteryTipPolicy.testHighUsageTip).isFalse();
assertThat(batteryTipPolicy.testSmartBatteryTip).isTrue();
+ assertThat(batteryTipPolicy.testLowBatteryTip).isTrue();
}
@Test
@@ -100,11 +102,12 @@
assertThat(batteryTipPolicy.reducedBatteryEnabled).isFalse();
assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(50);
assertThat(batteryTipPolicy.lowBatteryEnabled).isFalse();
- assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(16);
+ assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(3);
assertThat(batteryTipPolicy.dataHistoryRetainDay).isEqualTo(30);
assertThat(batteryTipPolicy.excessiveBgDrainPercentage).isEqualTo(10);
assertThat(batteryTipPolicy.testBatterySaverTip).isFalse();
assertThat(batteryTipPolicy.testHighUsageTip).isFalse();
assertThat(batteryTipPolicy.testSmartBatteryTip).isFalse();
+ assertThat(batteryTipPolicy.testLowBatteryTip).isFalse();
}
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
index 1f4affa..9764559 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
@@ -17,12 +17,15 @@
package com.android.settings.fuelgauge.batterytip.detectors;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.spy;
-import android.text.format.DateUtils;
+import android.content.Context;
+import android.os.PowerManager;
import com.android.settings.fuelgauge.BatteryInfo;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
+import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
@@ -31,8 +34,12 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPowerManager;
import org.robolectric.util.ReflectionHelpers;
+import java.util.concurrent.TimeUnit;
+
@RunWith(SettingsRobolectricTestRunner.class)
public class LowBatteryDetectorTest {
@@ -40,36 +47,68 @@
private BatteryInfo mBatteryInfo;
private BatteryTipPolicy mPolicy;
private LowBatteryDetector mLowBatteryDetector;
+ private ShadowPowerManager mShadowPowerManager;
+ private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mPolicy = spy(new BatteryTipPolicy(RuntimeEnvironment.application));
+ mContext = RuntimeEnvironment.application;
+ mShadowPowerManager = Shadows.shadowOf(mContext.getSystemService(PowerManager.class));
ReflectionHelpers.setField(mPolicy, "lowBatteryEnabled", true);
+ ReflectionHelpers.setField(mPolicy, "lowBatteryHour", 3);
+ mBatteryInfo.discharging = true;
- mLowBatteryDetector = new LowBatteryDetector(mPolicy, mBatteryInfo);
+ mLowBatteryDetector = new LowBatteryDetector(mContext, mPolicy, mBatteryInfo);
}
@Test
public void testDetect_disabledByPolicy_tipInvisible() {
ReflectionHelpers.setField(mPolicy, "lowBatteryEnabled", false);
+ mShadowPowerManager.setIsPowerSaveMode(true);
assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
}
@Test
- public void testDetect_shortBatteryLife_tipVisible() {
- mBatteryInfo.discharging = true;
- mBatteryInfo.remainingTimeUs = DateUtils.MINUTE_IN_MILLIS;
+ public void testDetect_enabledByTest_tipNew() {
+ ReflectionHelpers.setField(mPolicy, "testLowBatteryTip", true);
- assertThat(mLowBatteryDetector.detect().isVisible()).isTrue();
+ assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
}
@Test
- public void testDetect_longBatteryLife_tipInvisible() {
- mBatteryInfo.discharging = true;
- mBatteryInfo.remainingTimeUs = DateUtils.DAY_IN_MILLIS;
+ public void testDetect_lowBattery_tipNew() {
+ mBatteryInfo.batteryLevel = 3;
+ mBatteryInfo.remainingTimeUs = TimeUnit.DAYS.toMillis(1);
+ assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
+
+ mBatteryInfo.batteryLevel = 50;
+ mBatteryInfo.remainingTimeUs = TimeUnit.MINUTES.toMillis(1);
+ assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
+ }
+
+ @Test
+ public void testDetect_batterySaverOn_tipHandled() {
+ mShadowPowerManager.setIsPowerSaveMode(true);
+
+ assertThat(mLowBatteryDetector.detect().getState())
+ .isEqualTo(BatteryTip.StateType.HANDLED);
+ }
+
+ @Test
+ public void testDetect_charging_tipInvisible() {
+ mBatteryInfo.discharging = false;
+
+ assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
+ }
+
+ @Test
+ public void testDetect_noEarlyWarning_tipInvisible() {
+ mBatteryInfo.remainingTimeUs = TimeUnit.DAYS.toMicros(1);
+ mBatteryInfo.batteryLevel = 100;
assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
new file mode 100644
index 0000000..359d260
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 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.fuelgauge.batterytip.tips;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.Parcel;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class LowBatteryTipTest {
+
+ private static final CharSequence SUMMARY = "Only 15 minutes left";
+
+ @Mock
+ private MetricsFeatureProvider mMetricsFeatureProvider;
+ private Context mContext;
+ private LowBatteryTip mLowBatteryTip;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mLowBatteryTip = new LowBatteryTip(BatteryTip.StateType.NEW, false /* powerSaveModeOn */,
+ SUMMARY);
+ }
+
+ @Test
+ public void testParcelable() {
+ Parcel parcel = Parcel.obtain();
+ mLowBatteryTip.writeToParcel(parcel, mLowBatteryTip.describeContents());
+ parcel.setDataPosition(0);
+
+ final LowBatteryTip parcelTip = new LowBatteryTip(parcel);
+
+ assertThat(parcelTip.isPowerSaveModeOn()).isFalse();
+ assertThat(parcelTip.getSummary(mContext)).isEqualTo(SUMMARY);
+ }
+
+ @Test
+ public void getSummary_tipHandled_showSummary() {
+ mLowBatteryTip.mState = BatteryTip.StateType.HANDLED;
+
+ assertThat(mLowBatteryTip.getSummary(mContext)).isEqualTo("Some features may be limited");
+ }
+
+ @Test
+ public void getSummary_tipNew_showSummary() {
+ mLowBatteryTip.mState = BatteryTip.StateType.NEW;
+
+ assertThat(mLowBatteryTip.getSummary(mContext)).isEqualTo(SUMMARY);
+ }
+
+ @Test
+ public void log_lowBatteryActionWithCorrectState() {
+ mLowBatteryTip.log(mContext, mMetricsFeatureProvider);
+
+ verify(mMetricsFeatureProvider).action(mContext,
+ MetricsProto.MetricsEvent.ACTION_LOW_BATTERY_TIP, BatteryTip.StateType.NEW);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
index d4b7706..df40ba5 100644
--- a/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/GesturePreferenceControllerTest.java
@@ -204,7 +204,7 @@
@Override
public int getAvailabilityStatus() {
- return mIsPrefAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return mIsPrefAvailable ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
index 360609b..4107b73 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
@@ -18,35 +18,32 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
import android.os.UserManager;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
+import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager;
-import java.util.ArrayList;
-import java.util.List;
-
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = SettingsShadowResources.class)
public class SwipeUpPreferenceControllerTest {
private Context mContext;
@@ -58,11 +55,21 @@
@Before
public void setUp() {
+ SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
+ true);
+ SettingsShadowResources.overrideResource(
+ com.android.internal.R.bool.config_swipe_up_gesture_default, true);
+
mContext = RuntimeEnvironment.application;
mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
mController = new SwipeUpPreferenceController(mContext, KEY_SWIPE_UP);
}
+ @After
+ public void tearDown() {
+ SettingsShadowResources.reset();
+ }
+
@Test
public void testIsGestureAvailable_matchingServiceExists_shouldReturnTrue() {
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
@@ -75,19 +82,45 @@
}
@Test
+ public void testIsGestureAvailable_overlayDisabled_matchingServiceExists_shouldReturnFalse() {
+ SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
+ false);
+
+ final ComponentName recentsComponentName = ComponentName.unflattenFromString(
+ mContext.getString(com.android.internal.R.string.config_recentsComponentName));
+ final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
+ .setPackage(recentsComponentName.getPackageName());
+ mPackageManager.addResolveInfoForIntent(quickStepIntent, new ResolveInfo());
+
+ assertThat(SwipeUpPreferenceController.isGestureAvailable(mContext)).isFalse();
+ }
+
+ @Test
public void testIsGestureAvailable_noMatchingServiceExists_shouldReturnFalse() {
assertThat(SwipeUpPreferenceController.isGestureAvailable(mContext)).isFalse();
}
@Test
- public void testIsChecked_configIsSet_shouldReturnTrue() {
+ public void testIsChecked_defaultIsTrue_shouldReturnTrue() {
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void testIsChecked_defaultIsFalse_shouldReturnFalse() {
+ SettingsShadowResources.overrideResource(
+ com.android.internal.R.bool.config_swipe_up_gesture_default, false);
+ assertThat(mController.isChecked()).isFalse();
+ }
+
+ @Test
+ public void testIsChecked_setCheckedTrue_shouldReturnTrue() {
// Set the setting to be enabled.
mController.setChecked(true);
assertThat(mController.isChecked()).isTrue();
}
@Test
- public void testIsChecked_configIsNotSet_shouldReturnFalse() {
+ public void testIsChecked_setCheckedFalse_shouldReturnFalse() {
// Set the setting to be disabled.
mController.setChecked(false);
assertThat(mController.isChecked()).isFalse();
diff --git a/tests/robotests/src/com/android/settings/inputmethod/GameControllerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/GameControllerPreferenceControllerTest.java
index 61283fa..e5ecd6d 100644
--- a/tests/robotests/src/com/android/settings/inputmethod/GameControllerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/inputmethod/GameControllerPreferenceControllerTest.java
@@ -17,7 +17,8 @@
package com.android.settings.inputmethod;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -89,7 +90,7 @@
when(mInputDevice.isVirtual()).thenReturn(false);
when(mInputDevice.getVibrator().hasVibrator()).thenReturn(false);
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
@@ -98,14 +99,14 @@
when(mInputManager.getInputDevice(1)).thenReturn(mInputDevice);
when(mInputDevice.isVirtual()).thenReturn(true);
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_hasNoDevice_shouldReturnDisabled() {
when(mInputManager.getInputDeviceIds()).thenReturn(new int[] {});
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
@@ -113,7 +114,7 @@
public void getAvailabilityStatus_ifDisabled_shouldReturnDisabled() {
mController = new GameControllerPreferenceController(mContext, "testkey");
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
index f999194..12ecbfe 100644
--- a/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
@@ -18,8 +18,6 @@
import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF;
import static com.android.settings.notification.BadgingNotificationPreferenceController.ON;
diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
index 675ac57..8fef5fc 100644
--- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
@@ -169,7 +169,7 @@
@Override
public int getAvailabilityStatus() {
- return mAvailable ? AVAILABLE : DISABLED_UNSUPPORTED;
+ return mAvailable ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
new file mode 100644
index 0000000..7a45d7f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2018 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.notification;
+
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ZenModeStarredContactsPreferenceControllerTest {
+
+ private ZenModeStarredContactsPreferenceController mCallsController;
+ private ZenModeStarredContactsPreferenceController mMessagesController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ListPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ @Mock
+ private Intent testIntent;
+ @Mock
+ private ComponentName mComponentName;
+ private Context mContext;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ when(testIntent.resolveActivity(any())).thenReturn(mComponentName);
+
+ mCallsController = new ZenModeStarredContactsPreferenceController(
+ mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_CALLS);
+ ReflectionHelpers.setField(mCallsController, "mBackend", mBackend);
+ ReflectionHelpers.setField(mCallsController, "mStarredContactsIntent", testIntent);
+ when(mPreferenceScreen.findPreference(mCallsController.getPreferenceKey()))
+ .thenReturn(mockPref);
+ mCallsController.displayPreference(mPreferenceScreen);
+
+ mMessagesController = new ZenModeStarredContactsPreferenceController(
+ mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_MESSAGES);
+ ReflectionHelpers.setField(mMessagesController, "mBackend", mBackend);
+ ReflectionHelpers.setField(mMessagesController, "mStarredContactsIntent", testIntent);
+ when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
+ .thenReturn(mockPref);
+ mMessagesController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void isAvailable_noCallers() {
+ when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(false);
+ assertThat(mCallsController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_anyCallers() {
+ when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(true);
+ when(mBackend.getPriorityCallSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+
+
+ assertThat(mCallsController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_starredCallers() {
+ when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(true);
+ when(mBackend.getPriorityCallSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+
+ assertThat(mCallsController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_noMessages() {
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(false);
+ assertThat(mMessagesController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_anyMessages() {
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true);
+ when(mBackend.getPriorityMessageSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+
+ assertThat(mMessagesController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_starredMessageContacts() {
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true);
+ when(mBackend.getPriorityMessageSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+
+ assertThat(mMessagesController.isAvailable()).isTrue();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceControllerTest.java
index 56fa1c2..14de98c 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectsCustomPreferenceControllerTest.java
@@ -150,18 +150,4 @@
verify(mockPref).setOnGearClickListener(any());
verify(mockPref).setOnRadioButtonClickListener(any());
}
-
- @Test
- public void select() {
- int interruptiveSuppressed = SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
- | SUPPRESSED_EFFECT_AMBIENT
- | SUPPRESSED_EFFECT_LIGHTS
- | SUPPRESSED_EFFECT_PEEK;
- mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
- mController.select();
- verify(mBackend).savePolicy(anyInt(), anyInt(), anyInt(), eq(interruptiveSuppressed));
- verify(mFeatureFactory.metricsFeatureProvider).action(eq(mContext),
- eq(ACTION_ZEN_CUSTOM),
- eq(true));
- }
}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index c7bf043..f03f88e 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -211,7 +211,7 @@
// Disable Setting
Settings.Global.putInt(mContext.getContentResolver(),
FakeToggleController.AVAILABILITY_KEY,
- BasePreferenceController.DISABLED_UNSUPPORTED);
+ BasePreferenceController.UNSUPPORTED_ON_DEVICE);
// Insert Fake Toggle into Database
final String key = "key";
@@ -245,7 +245,7 @@
// Disable Setting
Settings.Global.putInt(mContext.getContentResolver(),
FakeSliderController.AVAILABILITY_KEY,
- BasePreferenceController.DISABLED_UNSUPPORTED);
+ BasePreferenceController.UNSUPPORTED_ON_DEVICE);
// Insert Fake Slider into Database
final String key = "key";
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index a74e2ba..bd589bf 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -330,7 +330,7 @@
SliceData.SliceType.SWITCH);
Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
- BasePreferenceController.DISABLED_UNSUPPORTED);
+ BasePreferenceController.UNSUPPORTED_ON_DEVICE);
final Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
@@ -373,12 +373,12 @@
}
@Test
- public void testUnavailableUnknownSlice_validTitleSummary() {
+ public void testConditionallyUnavailableSlice_validTitleSummary() {
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
SliceData.SliceType.SWITCH);
Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
- BasePreferenceController.UNAVAILABLE_UNKNOWN);
+ BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
final Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
diff --git a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
index 87ada36..674d629 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
@@ -56,7 +56,6 @@
private static final String FAKE_TITLE = "title";
private static final String FAKE_SUMMARY = "summary";
private static final String FAKE_SCREEN_TITLE = "screen_title";
- private static final String FAKE_KEYWORDS = "a, b, c";
private static final String FAKE_FRAGMENT_CLASSNAME = FakeIndexProvider.class.getName();
private static final String FAKE_CONTROLLER_NAME = FakePreferenceController.class.getName();
private static final String ACCESSIBILITY_FRAGMENT = AccessibilitySettings.class.getName();
@@ -118,7 +117,7 @@
assertThat(fakeSlice.getTitle()).isEqualTo(FAKE_TITLE);
assertThat(fakeSlice.getSummary()).isEqualTo(FAKE_SUMMARY);
assertThat(fakeSlice.getScreenTitle()).isEqualTo(FAKE_SCREEN_TITLE);
- assertThat(fakeSlice.getKeywords()).isEqualTo(FAKE_KEYWORDS);
+ assertThat(fakeSlice.getKeywords()).isNull();
assertThat(fakeSlice.getIconResource()).isNotNull();
assertThat(fakeSlice.getUri()).isNull();
assertThat(fakeSlice.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_CLASSNAME);
diff --git a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
index e0877e4..272fd20 100644
--- a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
@@ -17,8 +17,17 @@
package com.android.settings.sound;
+import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_SCO;
+import static android.media.AudioManager.STREAM_RING;
+import static android.media.AudioManager.STREAM_VOICE_CALL;
+import static android.media.AudioSystem.DEVICE_OUT_ALL_SCO;
+import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
+import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
+import static android.media.AudioSystem.STREAM_MUSIC;
+
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
@@ -28,6 +37,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
@@ -48,7 +59,8 @@
import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothEventManager;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.HeadsetProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -59,7 +71,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowBluetoothDevice;
@@ -77,19 +88,24 @@
private static final String TEST_KEY = "Test_Key";
private static final String TEST_DEVICE_NAME_1 = "Test_A2DP_BT_Device_NAME_1";
private static final String TEST_DEVICE_NAME_2 = "Test_A2DP_BT_Device_NAME_2";
- private static final String TEST_DEVICE_ADDRESS_1 = "00:07:80:78:A4:69";
- private static final String TEST_DEVICE_ADDRESS_2 = "00:00:00:00:00:00";
+ private static final String TEST_DEVICE_ADDRESS_1 = "00:A1:A1:A1:A1:A1";
+ private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2";
+ private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3";
+ private final static long HISYNCID1 = 10;
+ private final static long HISYNCID2 = 11;
@Mock
private LocalBluetoothManager mLocalManager;
@Mock
private BluetoothEventManager mBluetoothEventManager;
@Mock
- private CachedBluetoothDevice mCachedBluetoothDevice;
- @Mock
private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
@Mock
private A2dpProfile mA2dpProfile;
+ @Mock
+ private HeadsetProfile mHeadsetProfile;
+ @Mock
+ private HearingAidProfile mHearingAidProfile;
private Context mContext;
private PreferenceScreen mScreen;
@@ -99,10 +115,13 @@
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice mBluetoothDevice;
- private ShadowBluetoothDevice mShadowBluetoothDevice;
+ private BluetoothDevice mLeftBluetoothHapDevice;
+ private BluetoothDevice mRightBluetoothHapDevice;
private LocalBluetoothManager mLocalBluetoothManager;
private AudioSwitchPreferenceController mController;
- private List<BluetoothDevice> mConnectedDevices;
+ private List<BluetoothDevice> mProfileConnectedDevices;
+ private List<BluetoothDevice> mHearingAidActiveDevices;
+ private List<BluetoothDevice> mEmptyDevices;
@Before
public void setUp() {
@@ -118,20 +137,27 @@
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+ when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ when(mLocalBluetoothProfileManager.getHeadsetProfile()).thenReturn(mHeadsetProfile);
mBluetoothManager = new BluetoothManager(mContext);
mBluetoothAdapter = mBluetoothManager.getAdapter();
- mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1);
- mShadowBluetoothDevice = Shadows.shadowOf(mBluetoothDevice);
- mShadowBluetoothDevice.setName(TEST_DEVICE_NAME_1);
- when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+ mBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1));
+ when(mBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_1);
+ when(mBluetoothDevice.isConnected()).thenReturn(true);
+
+ mLeftBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2));
+ when(mLeftBluetoothHapDevice.isConnected()).thenReturn(true);
+ mRightBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_3));
+ when(mRightBluetoothHapDevice.isConnected()).thenReturn(true);
mController = new AudioSwitchPreferenceControllerTestable(mContext, TEST_KEY);
mScreen = spy(new PreferenceScreen(mContext, null));
mPreference = new ListPreference(mContext);
- mConnectedDevices = new ArrayList<>(1);
- mConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices = new ArrayList<>();
+ mHearingAidActiveDevices = new ArrayList<>(2);
+ mEmptyDevices = new ArrayList<>(2);
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
when(mScreen.getContext()).thenReturn(mContext);
@@ -155,7 +181,7 @@
@Test
public void getAvailabilityStatus_whenNotVisible_isDisable() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.AUDIO_SWITCHER_SETTINGS, false);
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
@@ -179,7 +205,8 @@
@Test
public void onPreferenceChange_toThisDevice_shouldSetDefaultSummary() {
- mController.mConnectedDevices = mConnectedDevices;
+ mController.mConnectedDevices.clear();
+ mController.mConnectedDevices.add(mBluetoothDevice);
mController.onPreferenceChange(mPreference,
mContext.getText(R.string.media_output_default_summary));
@@ -194,7 +221,8 @@
*/
@Test
public void onPreferenceChange_toBtDevice_shouldSetBtDeviceName() {
- mController.mConnectedDevices = mConnectedDevices;
+ mController.mConnectedDevices.clear();
+ mController.mConnectedDevices.add(mBluetoothDevice);
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1);
@@ -210,12 +238,11 @@
ShadowBluetoothDevice shadowBluetoothDevice;
BluetoothDevice secondBluetoothDevice;
secondBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2);
- shadowBluetoothDevice = Shadows.shadowOf(secondBluetoothDevice);
+ shadowBluetoothDevice = shadowOf(secondBluetoothDevice);
shadowBluetoothDevice.setName(TEST_DEVICE_NAME_2);
- List<BluetoothDevice> connectedDevices = new ArrayList<>(2);
- connectedDevices.add(mBluetoothDevice);
- connectedDevices.add(secondBluetoothDevice);
- mController.mConnectedDevices = connectedDevices;
+ mController.mConnectedDevices.clear();
+ mController.mConnectedDevices.add(mBluetoothDevice);
+ mController.mConnectedDevices.add(secondBluetoothDevice);
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_2);
@@ -223,16 +250,263 @@
}
/**
- * mConnectedDevices is Null.
+ * mConnectedDevices is empty.
* onPreferenceChange should return false.
*/
@Test
public void onPreferenceChange_connectedDeviceIsNull_shouldReturnFalse() {
- mController.mConnectedDevices = null;
+ mController.mConnectedDevices.clear();
assertThat(mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1)).isFalse();
}
+ /**
+ * Audio stream output to bluetooth sco headset which is the subset of all sco device.
+ * isStreamFromOutputDevice should return true.
+ */
+ @Test
+ public void isStreamFromOutputDevice_outputDeviceIsBtScoHeadset_shouldReturnTrue() {
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO_HEADSET);
+
+ assertThat(mController.isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_ALL_SCO)).isTrue();
+ }
+
+ /**
+ * Audio stream is not STREAM_MUSIC or STREAM_VOICE_CALL.
+ * findActiveDevice should return null.
+ */
+ @Test
+ public void findActiveDevice_streamIsRing_shouldReturnNull() {
+ assertThat(mController.findActiveDevice(STREAM_RING)).isNull();
+ }
+
+ /**
+ * Audio stream is STREAM_MUSIC and output device is A2dp bluetooth device.
+ * findActiveDevice should return A2dp active device.
+ */
+ @Test
+ public void findActiveDevice_streamMusicToA2dpDevice_shouldReturnActiveA2dpDevice() {
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ when(mHeadsetProfile.getActiveDevice()).thenReturn(mLeftBluetoothHapDevice);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+
+ assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mBluetoothDevice);
+ }
+
+ /**
+ * Audio stream is STREAM_VOICE_CALL and output device is Hands free profile bluetooth device.
+ * findActiveDevice should return Hands free profile active device.
+ */
+ @Test
+ public void findActiveDevice_streamVoiceCallToHfpDevice_shouldReturnActiveHfpDevice() {
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mLeftBluetoothHapDevice);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+
+ assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo(mBluetoothDevice);
+ }
+
+ /**
+ * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid profile
+ * bluetooth device. And left side of HAP device is active.
+ * findActiveDevice should return hearing aid device active device.
+ */
+ @Test
+ public void findActiveDevice_streamToHapDeviceLeftActiveDevice_shouldReturnActiveHapDevice() {
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mController.mConnectedDevices.clear();
+ mController.mConnectedDevices.add(mBluetoothDevice);
+ mController.mConnectedDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.add(null);
+ when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+
+ assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mLeftBluetoothHapDevice);
+ assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo(
+ mLeftBluetoothHapDevice);
+ }
+
+ /**
+ * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid profile
+ * bluetooth device. And right side of HAP device is active.
+ * findActiveDevice should return hearing aid device active device.
+ */
+ @Test
+ public void findActiveDevice_streamToHapDeviceRightActiveDevice_shouldReturnActiveHapDevice() {
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mController.mConnectedDevices.clear();
+ mController.mConnectedDevices.add(mBluetoothDevice);
+ mController.mConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(null);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+
+ assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mRightBluetoothHapDevice);
+ assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo(
+ mRightBluetoothHapDevice);
+ }
+
+ /**
+ * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid
+ * profile bluetooth device. And both are active device.
+ * findActiveDevice should return only return the active device in mConnectedDevices.
+ */
+ @Test
+ public void findActiveDevice_streamToHapDeviceTwoActiveDevice_shouldReturnActiveHapDevice() {
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mController.mConnectedDevices.clear();
+ mController.mConnectedDevices.add(mBluetoothDevice);
+ mController.mConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+
+ assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mRightBluetoothHapDevice);
+ assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo(
+ mRightBluetoothHapDevice);
+ }
+
+ /**
+ * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid
+ * profile bluetooth device. And none of them are active.
+ * findActiveDevice should return null.
+ */
+ @Test
+ public void findActiveDevice_streamToOtherDevice_shouldReturnActiveHapDevice() {
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mController.mConnectedDevices.clear();
+ mController.mConnectedDevices.add(mBluetoothDevice);
+ mController.mConnectedDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+
+ assertThat(mController.findActiveDevice(STREAM_MUSIC)).isNull();
+ assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isNull();
+ }
+
+ /**
+ * Two hearing aid devices with different HisyncId
+ * getConnectedHearingAidDevices should add both device to list.
+ */
+ @Test
+ public void getConnectedHearingAidDevices_deviceHisyncIdIsDifferent_shouldAddBothToList() {
+ mEmptyDevices.clear();
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2);
+
+ mEmptyDevices.addAll(mController.getConnectedHearingAidDevices());
+
+ assertThat(mEmptyDevices).containsExactly(mLeftBluetoothHapDevice,
+ mRightBluetoothHapDevice);
+ }
+
+ /**
+ * Two hearing aid devices with same HisyncId
+ * getConnectedHearingAidDevices should only add first device to list.
+ */
+ @Test
+ public void getConnectedHearingAidDevices_deviceHisyncIdIsSame_shouldAddOneToList() {
+ mEmptyDevices.clear();
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mEmptyDevices.addAll(mController.getConnectedHearingAidDevices());
+
+ assertThat(mEmptyDevices).containsExactly(mLeftBluetoothHapDevice);
+ }
+
+ /**
+ * One A2dp device is connected.
+ * getConnectedA2dpDevices should add this device to list.
+ */
+ @Test
+ public void getConnectedA2dpDevices_oneConnectedA2dpDevice_shouldAddDeviceToList() {
+ mEmptyDevices.clear();
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+
+ mEmptyDevices.addAll(mController.getConnectedA2dpDevices());
+
+ assertThat(mEmptyDevices).containsExactly(mBluetoothDevice);
+ }
+
+ /**
+ * More than one A2dp devices are connected.
+ * getConnectedA2dpDevices should add all devices to list.
+ */
+ @Test
+ public void getConnectedA2dpDevices_moreThanOneConnectedA2dpDevice_shouldAddDeviceToList() {
+ mEmptyDevices.clear();
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+
+ mEmptyDevices.addAll(mController.getConnectedA2dpDevices());
+
+ assertThat(mEmptyDevices).containsExactly(mBluetoothDevice, mLeftBluetoothHapDevice);
+ }
+
+ /**
+ * One hands free profile device is connected.
+ * getConnectedA2dpDevices should add this device to list.
+ */
+ @Test
+ public void getConnectedHfpDevices_oneConnectedHfpDevice_shouldAddDeviceToList() {
+ mEmptyDevices.clear();
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ when(mHeadsetProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+
+ mEmptyDevices.addAll(mController.getConnectedHfpDevices());
+
+ assertThat(mEmptyDevices).containsExactly(mBluetoothDevice);
+ }
+
+ /**
+ * More than one hands free profile devices are connected.
+ * getConnectedA2dpDevices should add all devices to list.
+ */
+ @Test
+ public void getConnectedHfpDevices_moreThanOneConnectedHfpDevice_shouldAddDeviceToList() {
+ mEmptyDevices.clear();
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ when(mHeadsetProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+
+ mEmptyDevices.addAll(mController.getConnectedHfpDevices());
+
+ assertThat(mEmptyDevices).containsExactly(mBluetoothDevice, mLeftBluetoothHapDevice);
+ }
+
private class AudioSwitchPreferenceControllerTestable extends
AudioSwitchPreferenceController {
AudioSwitchPreferenceControllerTestable(Context context, String key) {
diff --git a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
index 0692c9c..db09eab 100644
--- a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java
@@ -17,12 +17,16 @@
package com.android.settings.sound;
+import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
+import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -41,8 +45,8 @@
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settings.testutils.shadow.ShadowMediaRouter;
import com.android.settingslib.bluetooth.BluetoothEventManager;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HeadsetProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -53,7 +57,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowBluetoothDevice;
@@ -69,21 +72,27 @@
)
public class HandsFreeProfileOutputPreferenceControllerTest {
private static final String TEST_KEY = "Test_Key";
- private static final String TEST_DEVICE_NAME_1 = "Test_HAP_BT_Device_NAME_1";
- private static final String TEST_DEVICE_NAME_2 = "Test_HAP_BT_Device_NAME_2";
- private static final String TEST_DEVICE_ADDRESS_1 = "00:07:80:78:A4:69";
- private static final String TEST_DEVICE_ADDRESS_2 = "00:00:00:00:00:00";
+ private static final String TEST_DEVICE_NAME_1 = "Test_HFP_BT_Device_NAME_1";
+ private static final String TEST_DEVICE_NAME_2 = "Test_HFP_BT_Device_NAME_2";
+ private static final String TEST_HAP_DEVICE_NAME_1 = "Test_HAP_BT_Device_NAME_1";
+ private static final String TEST_HAP_DEVICE_NAME_2 = "Test_HAP_BT_Device_NAME_2";
+ private static final String TEST_DEVICE_ADDRESS_1 = "00:A1:A1:A1:A1:A1";
+ private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2";
+ private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3";
+ private static final String TEST_DEVICE_ADDRESS_4 = "00:D4:D4:D4:D4:D4";
+ private final static long HISYNCID1 = 10;
+ private final static long HISYNCID2 = 11;
@Mock
private LocalBluetoothManager mLocalManager;
@Mock
private BluetoothEventManager mBluetoothEventManager;
@Mock
- private CachedBluetoothDevice mCachedBluetoothDevice;
- @Mock
private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
@Mock
private HeadsetProfile mHeadsetProfile;
+ @Mock
+ private HearingAidProfile mHearingAidProfile;
private Context mContext;
private PreferenceScreen mScreen;
@@ -93,10 +102,13 @@
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice mBluetoothDevice;
- private ShadowBluetoothDevice mShadowBluetoothDevice;
+ private BluetoothDevice mSecondBluetoothDevice;
+ private BluetoothDevice mLeftBluetoothHapDevice;
+ private BluetoothDevice mRightBluetoothHapDevice;
private LocalBluetoothManager mLocalBluetoothManager;
private AudioSwitchPreferenceController mController;
- private List<BluetoothDevice> mConnectedDevices;
+ private List<BluetoothDevice> mProfileConnectedDevices;
+ private List<BluetoothDevice> mHearingAidActiveDevices;
@Before
public void setUp() {
@@ -112,19 +124,32 @@
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
when(mLocalBluetoothProfileManager.getHeadsetProfile()).thenReturn(mHeadsetProfile);
+ when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
mBluetoothManager = new BluetoothManager(mContext);
mBluetoothAdapter = mBluetoothManager.getAdapter();
- mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1);
- mShadowBluetoothDevice = Shadows.shadowOf(mBluetoothDevice);
- mShadowBluetoothDevice.setName(TEST_DEVICE_NAME_1);
- when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+
+ mBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1));
+ when(mBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_1);
+ when(mBluetoothDevice.isConnected()).thenReturn(true);
+
+ mSecondBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2));
+ when(mSecondBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_2);
+ when(mSecondBluetoothDevice.isConnected()).thenReturn(true);
+
+ mLeftBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_3));
+ when(mLeftBluetoothHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME_1);
+ when(mLeftBluetoothHapDevice.isConnected()).thenReturn(true);
+
+ mRightBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_4));
+ when(mRightBluetoothHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME_2);
+ when(mRightBluetoothHapDevice.isConnected()).thenReturn(true);
mController = new HandsFreeProfileOutputPreferenceController(mContext, TEST_KEY);
mScreen = spy(new PreferenceScreen(mContext, null));
mPreference = new ListPreference(mContext);
- mConnectedDevices = new ArrayList<>(1);
- mConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices = new ArrayList<>();
+ mHearingAidActiveDevices = new ArrayList<>(2);
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
when(mScreen.getContext()).thenReturn(mContext);
@@ -140,8 +165,26 @@
ShadowBluetoothUtils.reset();
}
+ /**
+ * During a call, bluetooth device with HisyncId.
+ * HearingAidProfile should set active device to this device.
+ */
@Test
- public void setActiveBluetoothDevice_duringACalling_shouldSetBtDeviceActive() {
+ public void setActiveBluetoothDevice_btDeviceWithHisyncId_shouldSetBtDeviceActive() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.setActiveBluetoothDevice(mLeftBluetoothHapDevice);
+
+ verify(mHearingAidProfile).setActiveDevice(mLeftBluetoothHapDevice);
+ }
+
+ /**
+ * During a call, Bluetooth device without HisyncId.
+ * HeadsetProfile should set active device to this device.
+ */
+ @Test
+ public void setActiveBluetoothDevice_btDeviceWithoutHisyncId_shouldSetBtDeviceActive() {
mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mController.setActiveBluetoothDevice(mBluetoothDevice);
@@ -149,23 +192,60 @@
verify(mHeadsetProfile).setActiveDevice(mBluetoothDevice);
}
+ /**
+ * During a call, set active device to "this device".
+ * HeadsetProfile should set to null.
+ * HearingAidProfile should set to null.
+ */
+ @Test
+ public void setActiveBluetoothDevice_setNull_shouldSetNullToBothProfiles() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+
+ mController.setActiveBluetoothDevice(null);
+
+ verify(mHeadsetProfile).setActiveDevice(null);
+ verify(mHearingAidProfile).setActiveDevice(null);
+ }
+
+ /**
+ * In normal mode
+ * HeadsetProfile should not set active device.
+ */
+ @Test
+ public void setActiveBluetoothDevice_inNormalMode_shouldNotSetActiveDeviceToHeadsetProfile() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+
+ mController.setActiveBluetoothDevice(mBluetoothDevice);
+
+ verify(mHeadsetProfile, times(0)).setActiveDevice(any(BluetoothDevice.class));
+ }
+
+ /**
+ * Default status
+ * Preference should be invisible
+ * Summary should be default summary
+ */
@Test
public void updateState_shouldSetSummary() {
mController.updateState(mPreference);
+ assertThat(mPreference.isVisible()).isFalse();
assertThat(mPreference.getSummary()).isEqualTo(
mContext.getText(R.string.media_output_default_summary));
}
/**
- * One Headset Bluetooth device is available and activated
+ * One Hands Free Profile Bluetooth device is available and activated
* Preference should be visible
- * Preference summary should be activate device name
+ * Preference summary should be the activated device name
*/
@Test
public void updateState_oneHeadsetsAvailableAndActivated_shouldSetDeviceName() {
mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
- when(mHeadsetProfile.getConnectedDevices()).thenReturn(mConnectedDevices);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ when(mHeadsetProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
mController.updateState(mPreference);
@@ -175,29 +255,25 @@
}
/**
- * More than one Headset Bluetooth devices are available, and second device is active.
+ * More than one Hands Free Profile Bluetooth devices are available, and second
+ * device is active.
* Preference should be visible
- * Preference summary should be activate device name
+ * Preference summary should be the activated device name
*/
@Test
- public void updateState_moreThanOneHapBtDevicesAreAvailable_shouldSetActivatedDeviceName() {
- ShadowBluetoothDevice shadowBluetoothDevice;
+ public void updateState_moreThanOneHfpBtDevicesAreAvailable_shouldSetActivatedDeviceName() {
mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
- BluetoothDevice secondBluetoothDevice;
- secondBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2);
- shadowBluetoothDevice = Shadows.shadowOf(secondBluetoothDevice);
- shadowBluetoothDevice.setName(TEST_DEVICE_NAME_2);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO);
List<BluetoothDevice> connectedDevices = new ArrayList<>(2);
connectedDevices.add(mBluetoothDevice);
- connectedDevices.add(secondBluetoothDevice);
-
+ connectedDevices.add(mSecondBluetoothDevice);
when(mHeadsetProfile.getConnectedDevices()).thenReturn(connectedDevices);
- when(mHeadsetProfile.getActiveDevice()).thenReturn(secondBluetoothDevice);
+ when(mHeadsetProfile.getActiveDevice()).thenReturn(mSecondBluetoothDevice);
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isTrue();
- assertThat(mPreference.getSummary()).isEqualTo(secondBluetoothDevice.getName());
+ assertThat(mPreference.getSummary()).isEqualTo(mSecondBluetoothDevice.getName());
}
/**
@@ -209,8 +285,10 @@
@Test
public void updateState_withAvailableDevicesWiredHeadsetActivated_shouldSetDefaultSummary() {
mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
- mShadowAudioManager.setStream(DEVICE_OUT_USB_HEADSET);
- when(mHeadsetProfile.getConnectedDevices()).thenReturn(mConnectedDevices);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_USB_HEADSET);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ when(mHeadsetProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
when(mHeadsetProfile.getActiveDevice()).thenReturn(
mBluetoothDevice); // BT device is still activated in this case
@@ -238,4 +316,150 @@
assertThat(mPreference.getSummary()).isEqualTo(
mContext.getText(R.string.media_output_default_summary));
}
+
+ /**
+ * One hearing aid profile Bluetooth device is available and active.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ */
+ @Test
+ public void updateState_oneHapBtDeviceAreAvailable_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mLeftBluetoothHapDevice.getName());
+ }
+
+ /**
+ * More than one hearing aid profile Bluetooth devices are available, and second
+ * device is active.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ */
+ @Test
+ public void updateState_moreThanOneHapBtDevicesAreAvailable_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
+ }
+
+ /**
+ * Both hearing aid profile and hands free profile Bluetooth devices are available, and
+ * two hearing aid profile devices with same HisyncId. Both of HAP device are active,
+ * "left" side HAP device is added first.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ * ConnectedDevice should not contain second HAP device with same HisyncId
+ */
+ @Test
+ public void updateState_hapBtDeviceWithSameId_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ //with same HisyncId, only the first one will remain in UI.
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mLeftBluetoothHapDevice.getName());
+ assertThat(mController.mConnectedDevices.contains(mLeftBluetoothHapDevice)).isTrue();
+ assertThat(mController.mConnectedDevices.contains(mRightBluetoothHapDevice)).isFalse();
+ }
+
+ /**
+ * Both hearing aid profile and hands free profile Bluetooth devices are available, and
+ * two hearing aid profile devices with same HisyncId. Both of HAP device are active,
+ * "right" side HAP device is added first.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ * ConnectedDevice should not contain second HAP device with same HisyncId
+ */
+ @Test
+ public void updateState_hapBtDeviceWithSameIdButDifferentOrder_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ //with same HisyncId, only the first one will remain in UI.
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mController.mConnectedDevices.contains(mRightBluetoothHapDevice)).isTrue();
+ assertThat(mController.mConnectedDevices.contains(mLeftBluetoothHapDevice)).isFalse();
+ assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
+ }
+
+ /**
+ * Both hearing aid profile and hands free profile Bluetooth devices are available, and
+ * two hearing aid profile devices with different HisyncId. One of HAP device is active.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ * ConnectedDevice should contain both HAP device with different HisyncId
+ */
+ @Test
+ public void updateState_hapBtDeviceWithDifferentId_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(null);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
+ assertThat(mController.mConnectedDevices).containsExactly(mBluetoothDevice,
+ mLeftBluetoothHapDevice, mRightBluetoothHapDevice);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
index b62e6b3..b777239 100644
--- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
@@ -17,13 +17,17 @@
package com.android.settings.sound;
+import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
+import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
import static android.media.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -43,7 +47,7 @@
import com.android.settings.testutils.shadow.ShadowMediaRouter;
import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.BluetoothEventManager;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -54,7 +58,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowBluetoothDevice;
@@ -72,19 +75,25 @@
private static final String TEST_KEY = "Test_Key";
private static final String TEST_DEVICE_NAME_1 = "Test_A2DP_BT_Device_NAME_1";
private static final String TEST_DEVICE_NAME_2 = "Test_A2DP_BT_Device_NAME_2";
- private static final String TEST_DEVICE_ADDRESS_1 = "00:07:80:78:A4:69";
- private static final String TEST_DEVICE_ADDRESS_2 = "00:00:00:00:00:00";
+ private static final String TEST_HAP_DEVICE_NAME_1 = "Test_HAP_BT_Device_NAME_1";
+ private static final String TEST_HAP_DEVICE_NAME_2 = "Test_HAP_BT_Device_NAME_2";
+ private static final String TEST_DEVICE_ADDRESS_1 = "00:A1:A1:A1:A1:A1";
+ private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2";
+ private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3";
+ private static final String TEST_DEVICE_ADDRESS_4 = "00:D4:D4:D4:D4:D4";
+ private final static long HISYNCID1 = 10;
+ private final static long HISYNCID2 = 11;
@Mock
private LocalBluetoothManager mLocalManager;
@Mock
private BluetoothEventManager mBluetoothEventManager;
@Mock
- private CachedBluetoothDevice mCachedBluetoothDevice;
- @Mock
private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
@Mock
private A2dpProfile mA2dpProfile;
+ @Mock
+ private HearingAidProfile mHearingAidProfile;
private Context mContext;
private PreferenceScreen mScreen;
@@ -94,10 +103,13 @@
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice mBluetoothDevice;
- private ShadowBluetoothDevice mShadowBluetoothDevice;
+ private BluetoothDevice mSecondBluetoothDevice;
+ private BluetoothDevice mLeftBluetoothHapDevice;
+ private BluetoothDevice mRightBluetoothHapDevice;
private LocalBluetoothManager mLocalBluetoothManager;
private AudioSwitchPreferenceController mController;
- private List<BluetoothDevice> mConnectedDevices;
+ private List<BluetoothDevice> mProfileConnectedDevices;
+ private List<BluetoothDevice> mHearingAidActiveDevices;
@Before
public void setUp() {
@@ -113,19 +125,32 @@
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+ when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
mBluetoothManager = new BluetoothManager(mContext);
mBluetoothAdapter = mBluetoothManager.getAdapter();
- mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1);
- mShadowBluetoothDevice = Shadows.shadowOf(mBluetoothDevice);
- mShadowBluetoothDevice.setName(TEST_DEVICE_NAME_1);
- when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+
+ mBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1));
+ when(mBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_1);
+ when(mBluetoothDevice.isConnected()).thenReturn(true);
+
+ mSecondBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2));
+ when(mSecondBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_2);
+ when(mSecondBluetoothDevice.isConnected()).thenReturn(true);
+
+ mLeftBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_3));
+ when(mLeftBluetoothHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME_1);
+ when(mLeftBluetoothHapDevice.isConnected()).thenReturn(true);
+
+ mRightBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_4));
+ when(mRightBluetoothHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME_2);
+ when(mRightBluetoothHapDevice.isConnected()).thenReturn(true);
mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
mScreen = spy(new PreferenceScreen(mContext, null));
mPreference = new ListPreference(mContext);
- mConnectedDevices = new ArrayList<>(1);
- mConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices = new ArrayList<>();
+ mHearingAidActiveDevices = new ArrayList<>(2);
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
when(mScreen.getContext()).thenReturn(mContext);
@@ -141,8 +166,26 @@
ShadowBluetoothUtils.reset();
}
+ /**
+ * In normal mode, bluetooth device with HisyncId.
+ * HearingAidProfile should set active device to this device.
+ */
@Test
- public void setActiveBluetoothDevice_withoutRingAndCall_shouldSetBtDeviceActive() {
+ public void setActiveBluetoothDevice_btDeviceWithHisyncId_shouldSetBtDeviceActive() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.setActiveBluetoothDevice(mLeftBluetoothHapDevice);
+
+ verify(mHearingAidProfile).setActiveDevice(mLeftBluetoothHapDevice);
+ }
+
+ /**
+ * In normal mode, bluetooth device without HisyncId.
+ * A2dpProfile should set active device to this device.
+ */
+ @Test
+ public void setActiveBluetoothDevice_btDeviceWithoutHisyncId_shouldSetBtDeviceActive() {
mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
mController.setActiveBluetoothDevice(mBluetoothDevice);
@@ -150,16 +193,50 @@
verify(mA2dpProfile).setActiveDevice(mBluetoothDevice);
}
+ /**
+ * In normal mode, set active device to "this device".
+ * A2dpProfile should set to null.
+ * HearingAidProfile should set to null.
+ */
+ @Test
+ public void setActiveBluetoothDevice_setNull_shouldSetNullToBothProfiles() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+
+ mController.setActiveBluetoothDevice(null);
+
+ verify(mA2dpProfile).setActiveDevice(null);
+ verify(mHearingAidProfile).setActiveDevice(null);
+ }
+
+ /**
+ * During a call
+ * A2dpProfile should not set active device.
+ */
+ @Test
+ public void setActiveBluetoothDevice_duringACall_shouldNotSetActiveDeviceToA2dpProfile() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+
+ mController.setActiveBluetoothDevice(mBluetoothDevice);
+
+ verify(mA2dpProfile, times(0)).setActiveDevice(any(BluetoothDevice.class));
+ }
+
+ /**
+ * Default status
+ * Preference should be invisible
+ * Summary should be default summary
+ */
@Test
public void updateState_shouldSetSummary() {
mController.updateState(mPreference);
+ assertThat(mPreference.isVisible()).isFalse();
assertThat(mPreference.getSummary()).isEqualTo(
mContext.getText(R.string.media_output_default_summary));
}
/**
- * On going call state:
+ * During a call
* Preference should be invisible
* Default string should be "Unavailable during calls"
*/
@@ -199,7 +276,7 @@
*/
@Test
public void updateState_mediaStreamIsCapturedByCast_shouldDisableAndSetDefaultSummary() {
- mShadowAudioManager.setStream(DEVICE_OUT_REMOTE_SUBMIX);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_REMOTE_SUBMIX);
mController.updateState(mPreference);
@@ -211,12 +288,15 @@
/**
* One A2DP Bluetooth device is available and active.
* Preference should be visible
- * Preference summary should be activate device name
+ * Preference summary should be the activated device name
*/
@Test
public void updateState_oneA2dpBtDeviceAreAvailable_shouldSetActivatedDeviceName() {
mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
- when(mA2dpProfile.getConnectedDevices()).thenReturn(mConnectedDevices);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
mController.updateState(mPreference);
@@ -228,27 +308,22 @@
/**
* More than one A2DP Bluetooth devices are available, and second device is active.
* Preference should be visible
- * Preference summary should be activate device name
+ * Preference summary should be the activated device name
*/
@Test
public void updateState_moreThanOneA2DpBtDevicesAreAvailable_shouldSetActivatedDeviceName() {
- ShadowBluetoothDevice shadowBluetoothDevice;
mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
- BluetoothDevice secondBluetoothDevice;
- secondBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2);
- shadowBluetoothDevice = Shadows.shadowOf(secondBluetoothDevice);
- shadowBluetoothDevice.setName(TEST_DEVICE_NAME_2);
- List<BluetoothDevice> connectedDevices = new ArrayList<>(2);
- connectedDevices.add(mBluetoothDevice);
- connectedDevices.add(secondBluetoothDevice);
-
- when(mA2dpProfile.getConnectedDevices()).thenReturn(connectedDevices);
- when(mA2dpProfile.getActiveDevice()).thenReturn(secondBluetoothDevice);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices.add(mSecondBluetoothDevice);
+ when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mSecondBluetoothDevice);
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isTrue();
- assertThat(mPreference.getSummary()).isEqualTo(secondBluetoothDevice.getName());
+ assertThat(mPreference.getSummary()).isEqualTo(mSecondBluetoothDevice.getName());
}
/**
@@ -259,16 +334,18 @@
@Test
public void updateState_a2dpDevicesAvailableWiredHeadsetIsActivated_shouldSetDefaultSummary() {
mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
- mShadowAudioManager.setStream(DEVICE_OUT_USB_HEADSET);
- when(mA2dpProfile.getConnectedDevices()).thenReturn(mConnectedDevices);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_USB_HEADSET);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
when(mA2dpProfile.getActiveDevice()).thenReturn(
mBluetoothDevice); // BT device is still activated in this case
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isTrue();
- String defaultString = mContext.getString(R.string.media_output_default_summary);
- assertThat(mPreference.getSummary()).isEqualTo(defaultString);
+ assertThat(mPreference.getSummary()).isEqualTo(
+ mContext.getString(R.string.media_output_default_summary));
}
@@ -280,13 +357,161 @@
@Test
public void updateState_a2dpDevicesAvailableCurrentDeviceActivated_shouldSetDefaultSummary() {
mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
- when(mA2dpProfile.getConnectedDevices()).thenReturn(mConnectedDevices);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
when(mA2dpProfile.getActiveDevice()).thenReturn(null);
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isTrue();
- String defaultString = mContext.getString(R.string.media_output_default_summary);
- assertThat(mPreference.getSummary()).isEqualTo(defaultString);
+ assertThat(mPreference.getSummary()).isEqualTo(
+ mContext.getString(R.string.media_output_default_summary));
+ }
+
+ /**
+ * One hearing aid profile Bluetooth device is available and active.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ */
+ @Test
+ public void updateState_oneHapBtDeviceAreAvailable_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mLeftBluetoothHapDevice.getName());
+ }
+
+ /**
+ * More than one hearing aid profile Bluetooth devices are available, and second
+ * device is active.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ */
+ @Test
+ public void updateState_moreThanOneHapBtDevicesAreAvailable_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
+ }
+
+ /**
+ * Both hearing aid profile and A2dp Bluetooth devices are available, and two hearing aid
+ * profile devices with same HisyncId are active. Both of HAP device are active,
+ * "left" side HAP device is added first.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ * ConnectedDevice should not contain second HAP device with same HisyncId
+ */
+ @Test
+ public void updateState_hapBtDeviceWithSameId_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ //with same HisyncId, first one will remain in UI.
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mLeftBluetoothHapDevice.getName());
+ assertThat(mController.mConnectedDevices.contains(mLeftBluetoothHapDevice)).isTrue();
+ assertThat(mController.mConnectedDevices.contains(mRightBluetoothHapDevice)).isFalse();
+ }
+
+ /**
+ * Both hearing aid profile and A2dp Bluetooth devices are available, and two hearing aid
+ * profile devices with same HisyncId. Both of HAP device are active,
+ * "right" side HAP device is added first.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ * ConnectedDevice should not contain second HAP device with same HisyncId
+ */
+ @Test
+ public void updateState_hapBtDeviceWithSameIdButDifferentOrder_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ //with same HisyncId, first one will remain in UI.
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
+ assertThat(mController.mConnectedDevices.contains(mRightBluetoothHapDevice)).isTrue();
+ assertThat(mController.mConnectedDevices.contains(mLeftBluetoothHapDevice)).isFalse();
+ }
+
+ /**
+ * Both hearing aid profile and A2dp Bluetooth devices are available, and two hearing aid
+ * profile devices with different HisyncId. One of HAP device is active.
+ * Preference should be visible
+ * Preference summary should be the activated device name
+ * ConnectedDevice should contain both HAP device with different HisyncId
+ */
+ @Test
+ public void updateState_hapBtDeviceWithDifferentId_shouldSetActivatedDeviceName() {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
+ mProfileConnectedDevices.clear();
+ mProfileConnectedDevices.add(mBluetoothDevice);
+ mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
+ mProfileConnectedDevices.add(mRightBluetoothHapDevice);
+ mHearingAidActiveDevices.clear();
+ mHearingAidActiveDevices.add(null);
+ mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
+ when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
+ when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
+ assertThat(mController.mConnectedDevices).containsExactly(mBluetoothDevice,
+ mLeftBluetoothHapDevice, mRightBluetoothHapDevice);
}
}
diff --git a/tests/robotests/src/com/android/settings/testutils/SliceTester.java b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
index a7840e8..529e32d 100644
--- a/tests/robotests/src/com/android/settings/testutils/SliceTester.java
+++ b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
@@ -19,10 +19,10 @@
import static android.app.slice.Slice.HINT_TITLE;
import static android.app.slice.SliceItem.FORMAT_TEXT;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
-import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
-import static com.android.settings.core.BasePreferenceController.UNAVAILABLE_UNKNOWN;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
@@ -30,7 +30,9 @@
import android.content.Context;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import androidx.slice.Slice;
import androidx.slice.SliceItem;
@@ -151,8 +153,8 @@
final int availabilityStatus = SliceBuilderUtils.getPreferenceController(context,
sliceData).getAvailabilityStatus();
switch (availabilityStatus) {
- case DISABLED_UNSUPPORTED:
- case UNAVAILABLE_UNKNOWN:
+ case UNSUPPORTED_ON_DEVICE:
+ case CONDITIONALLY_UNAVAILABLE:
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getSettingsIntent(context));
break;
@@ -188,7 +190,10 @@
private static void assertKeywords(SliceMetadata metadata, SliceData data) {
final List<String> keywords = metadata.getSliceKeywords();
- final List<String> expectedKeywords = Arrays.asList(data.getKeywords().split(","));
+ final Set<String> expectedKeywords = new HashSet<>(
+ Arrays.asList(data.getKeywords().split(",")));
+ expectedKeywords.add(data.getTitle());
+ expectedKeywords.add(data.getScreenTitle().toString());
assertThat(keywords).containsExactlyElementsIn(expectedKeywords);
}
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioManager.java
index 0de2156..88a0fb6 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioManager.java
@@ -41,7 +41,7 @@
@Implements(value = AudioManager.class, inheritImplementationMethods = true)
public class ShadowAudioManager extends org.robolectric.shadows.ShadowAudioManager {
private int mRingerMode;
- private int mStream;
+ private int mDeviceCodes;
private boolean mMusicActiveRemotely = false;
private ArrayList<AudioDeviceCallback> mDeviceCallbacks = new ArrayList();
@@ -79,8 +79,8 @@
return mMusicActiveRemotely;
}
- public void setStream(int stream) {
- mStream = stream;
+ public void setOutputDevice(int deviceCodes) {
+ mDeviceCodes = deviceCodes;
}
@Implementation
@@ -94,7 +94,7 @@
case STREAM_NOTIFICATION:
case STREAM_DTMF:
case STREAM_ACCESSIBILITY:
- return mStream;
+ return mDeviceCodes;
default:
return 0;
}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
index d445c0d..ddbc851 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
@@ -268,6 +268,19 @@
assertThat(hiddenSpinner.isEnabled()).isTrue();
}
+
+ @Test
+ public void hiddenSpinner_visibilityUpdatesCorrectly() {
+ View hiddenSpinner = mView.findViewById(R.id.hidden_settings);
+ assertThat(hiddenSpinner.isEnabled()).isFalse();
+ assertThat(hiddenSpinner.getVisibility()).isEqualTo(View.GONE);
+
+ mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */,
+ WifiConfigUiBase.MODE_CONNECT);
+ assertThat(hiddenSpinner.isEnabled()).isTrue();
+ assertThat(hiddenSpinner.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
public class TestWifiConfigController extends WifiConfigController {
private TestWifiConfigController(