Snap for 10179466 from f7e3a2ce45 to udc-qpr1-release

Change-Id: If0a51993d8c0c7224df2770f0bc3469f841cdeda
This commit is contained in:
Android Build Coastguard Worker
2023-05-23 01:24:10 +00:00
26 changed files with 498 additions and 342 deletions

View File

@@ -2644,6 +2644,8 @@
<string name="build_number">Build number</string>
<!-- About phone screen, tapping this button will take user to a seperate UI to check Google Play system update [CHAR LIMIT=60] -->
<string name="module_version">Google Play system update</string>
<!-- About phone screen, show a list of battery information [CHAR LIMIT=60] -->
<string name="battery_info">Battery information</string>
<!-- About phone screen, show when a value of some status item is unavailable. -->
<string name="device_info_not_available">Not available</string>
@@ -2715,6 +2717,14 @@
<string name="status_serial_number">Serial number</string>
<!-- About phone, status item title. How long the device has been running since its last reboot. -->
<string name="status_up_time">Up time</string>
<!-- About phone, status item title. The battery manufacture date. [CHAR LIMIT=60]-->
<string name="battery_manufacture_date">Manufacture date</string>
<!-- About phone, status item title. Date of first use of the battery. [CHAR LIMIT=60]-->
<string name="battery_first_use_date">Date of first use</string>
<!-- About phone, status item title. Count of battery full charge/discharge cycles [CHAR LIMIT=60]-->
<string name="battery_cycle_count">Cycle count</string>
<!-- SD card & phone storage settings summary. Displayed when the total memory usage is being calculated. Will be replaced with a number like "12.3 GB" when finished calucating. [CHAR LIMIT=30] -->
<string name="memory_calculating_size">Calculating\u2026</string>
@@ -7008,6 +7018,7 @@
<string name="keywords_sim_status_iccid_esim">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid, eid</string>
<string name="keywords_esim_eid">eid</string>
<string name="keywords_model_and_hardware">serial number, hardware version</string>
<string name="keywords_battery_info">battery info, manufacture date, cycle count, first use</string>
<string name="keywords_android_version">android security patch level, baseband version, kernel version</string>
<!-- Search keywords for dark mode settings [CHAR LIMIT=NONE] -->
<string name="keywords_dark_ui_mode">theme, light, dark, mode, light sensitivity, photophobia, make darker, darken, dark mode, migraine</string>

45
res/xml/battery_info.xml Normal file
View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/battery_info"
settings:keywords="@string/keywords_battery_info">
<Preference
android:key="battery_info_manufacture_date"
android:title="@string/battery_manufacture_date"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.deviceinfo.batteryinfo.BatteryManufactureDatePreferenceController"
settings:enableCopying="true"/>
<Preference
android:key="battery_info_first_use_date"
android:title="@string/battery_first_use_date"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.deviceinfo.batteryinfo.BatteryFirstUseDatePreferenceController"
settings:enableCopying="true"/>
<Preference
android:key="battery_info_cycle_count"
android:title="@string/battery_cycle_count"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.deviceinfo.batteryinfo.BatteryCycleCountPreferenceController"
settings:enableCopying="true"/>
</PreferenceScreen>

View File

@@ -144,6 +144,14 @@
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.deviceinfo.firmwareversion.FirmwareVersionSettings"
settings:controller="com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceController"/>
<!-- Battery information -->
<Preference
android:key="battery_info"
android:order="43"
android:title="@string/battery_info"
android:fragment="com.android.settings.deviceinfo.batteryinfo.BatteryInfoFragment"
settings:keywords="@string/keywords_battery_info"/>
</PreferenceCategory>
<PreferenceCategory

View File

@@ -64,14 +64,6 @@
settings:searchable="false"
settings:controller="com.android.settings.sound.HandsFreeProfileOutputPreferenceController"/>
<!-- Ring volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="ring_volume"
android:icon="@drawable/ic_notifications"
android:title="@string/ring_volume_option_title"
android:order="-160"
settings:controller="com.android.settings.notification.RingVolumePreferenceController"/>
<!-- Separate Ring volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="separate_ring_volume"

View File

@@ -59,7 +59,7 @@ import java.util.Optional;
* until {@link Slice} is fully loaded.
*/
public class BlockingPrefWithSliceController extends BasePreferenceController implements
LifecycleObserver, OnStart, OnStop, Observer<Slice>, BasePreferenceController.UiBlocker{
LifecycleObserver, OnStart, OnStop, Observer<Slice>, BasePreferenceController.UiBlocker {
private static final String TAG = "BlockingPrefWithSliceController";
private static final String PREFIX_KEY = "slice_preference_item_";
@@ -213,7 +213,8 @@ public class BlockingPrefWithSliceController extends BasePreferenceController im
} else {
expectedActivityIntent = intentFromSliceAction;
}
if (expectedActivityIntent != null) {
if (expectedActivityIntent != null && expectedActivityIntent.resolveActivity(
mContext.getPackageManager()) != null) {
Log.d(TAG, "setIntent: ActivityIntent" + expectedActivityIntent);
// Since UI needs to support the Settings' 2 panel feature, the intent can't use the
// FLAG_ACTIVITY_NEW_TASK. The above intent may have the FLAG_ACTIVITY_NEW_TASK
@@ -222,6 +223,7 @@ public class BlockingPrefWithSliceController extends BasePreferenceController im
preference.setIntent(expectedActivityIntent);
} else {
Log.d(TAG, "setIntent: Intent is null");
preference.setSelectable(false);
}
}

View File

@@ -94,6 +94,7 @@ import com.android.settings.deviceinfo.PrivateVolumeForget;
import com.android.settings.deviceinfo.PublicVolumeSettings;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFragment;
import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionSettings;
import com.android.settings.deviceinfo.legal.ModuleLicensesDashboard;
import com.android.settings.display.AutoBrightnessSettings;
@@ -371,7 +372,8 @@ public class SettingsGateway {
NfcAndPaymentFragment.class.getName(),
ColorAndMotionFragment.class.getName(),
LongBackgroundTasksDetails.class.getName(),
RegionalPreferencesEntriesFragment.class.getName()
RegionalPreferencesEntriesFragment.class.getName(),
BatteryInfoFragment.class.getName()
};
public static final String[] SETTINGS_FOR_RESTRICTED = {

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2023 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.deviceinfo.batteryinfo;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import com.android.settings.core.BasePreferenceController;
/**
* A controller that manages the information about battery cycle count.
*/
public class BatteryCycleCountPreferenceController extends BasePreferenceController {
public BatteryCycleCountPreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public CharSequence getSummary() {
final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
final Intent batteryStatus = mContext.registerReceiver(null, intentFilter);
final int cycleCount = batteryStatus.getIntExtra(BatteryManager.EXTRA_CYCLE_COUNT, -1);
return Integer.toString(cycleCount);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2023 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.deviceinfo.batteryinfo;
import android.content.Context;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
/**
* A controller that manages the information about battery first use date.
*/
public class BatteryFirstUseDatePreferenceController extends BasePreferenceController {
private BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
public BatteryFirstUseDatePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mBatteryInfoFeatureProvider = FeatureFactory.getFactory(
context).getBatteryInfoFeatureProvider();
}
@Override
public int getAvailabilityStatus() {
return mBatteryInfoFeatureProvider.isFirstUseDateAvailable()
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
return mBatteryInfoFeatureProvider.getFirstUseDateSummary();
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2023 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.deviceinfo.batteryinfo;
import android.app.settings.SettingsEnums;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
/**
* A fragment that shows battery hardware information.
*/
@SearchIndexable
public class BatteryInfoFragment extends DashboardFragment {
public static final String TAG = "BatteryInfo";
@Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_BATTERY_INFORMATION;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.battery_info;
}
@Override
protected String getLogTag() {
return TAG;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.battery_info);
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2023 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.deviceinfo.batteryinfo;
import android.content.Context;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
/**
* A controller that manages the information about battery manufacture date.
*/
public class BatteryManufactureDatePreferenceController extends BasePreferenceController {
private BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
public BatteryManufactureDatePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mBatteryInfoFeatureProvider = FeatureFactory.getFactory(
context).getBatteryInfoFeatureProvider();
}
@Override
public int getAvailabilityStatus() {
return mBatteryInfoFeatureProvider.isManufactureDateAvailable()
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
return mBatteryInfoFeatureProvider.getManufactureDateSummary();
}
}

View File

@@ -39,6 +39,8 @@ import java.util.List;
public class LanguageSettings extends DashboardFragment {
private static final String KEY_SPEECH_CATEGORY = "speech_category";
private static final String KEY_ON_DEVICE_RECOGNITION = "on_device_recognition_settings";
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
private static final String TAG = "LanguageSettings";
@@ -81,9 +83,9 @@ public class LanguageSettings extends DashboardFragment {
final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
new DefaultVoiceInputPreferenceController(context, lifecycle);
final TtsPreferenceController ttsPreferenceController =
new TtsPreferenceController(context);
new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
final OnDeviceRecognitionPreferenceController onDeviceRecognitionPreferenceController =
new OnDeviceRecognitionPreferenceController(context);
new OnDeviceRecognitionPreferenceController(context, KEY_ON_DEVICE_RECOGNITION);
controllers.add(defaultVoiceInputPreferenceController);
controllers.add(ttsPreferenceController);
@@ -103,6 +105,7 @@ public class LanguageSettings extends DashboardFragment {
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.language_settings) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);

View File

@@ -33,16 +33,10 @@ import java.util.Optional;
/** Controller of the On-device recognition preference. */
public class OnDeviceRecognitionPreferenceController extends BasePreferenceController {
private static final String KEY_ON_DEVICE_RECOGNITION = "on_device_recognition_settings";
private static final String TAG = "OnDeviceRecognitionPreferenceController";
private Optional<Intent> mIntent;
public OnDeviceRecognitionPreferenceController(Context context) {
this(context, KEY_ON_DEVICE_RECOGNITION);
}
public OnDeviceRecognitionPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@@ -57,10 +51,6 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr
: CONDITIONALLY_UNAVAILABLE;
}
public String getPreferenceKey() {
return KEY_ON_DEVICE_RECOGNITION;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
@@ -140,4 +130,4 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr
return new Intent(Intent.ACTION_MAIN).setComponent(chosenRecognizer.mSettings);
}
}
}

View File

@@ -26,15 +26,9 @@ import com.android.settings.core.BasePreferenceController;
public class TtsPreferenceController extends BasePreferenceController {
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
@VisibleForTesting
TtsEngines mTtsEngines;
public TtsPreferenceController(Context context) {
this(context, KEY_TEXT_TO_SPEECH);
}
public TtsPreferenceController(Context context, String key) {
super(context, key);
mTtsEngines = new TtsEngines(context);
@@ -46,8 +40,4 @@ public class TtsPreferenceController extends BasePreferenceController {
mContext.getResources().getBoolean(R.bool.config_show_tts_settings_summary)
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
public String getPreferenceKey() {
return KEY_TEXT_TO_SPEECH;
}
}
}

View File

@@ -16,29 +16,23 @@
package com.android.settings.notification;
import android.app.ActivityThread;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.DeviceConfig;
import android.service.notification.NotificationListenerService;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.PreferenceScreen;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Set;
/**
* Update notification volume icon in Settings in response to user adjusting volume.
*/
@@ -84,37 +78,11 @@ public class NotificationVolumePreferenceController extends
updateEnabledState();
}
/**
* Only display the notification slider when the corresponding device config flag is set
*/
private void onDeviceConfigChange(DeviceConfig.Properties properties) {
Set<String> changeSet = properties.getKeyset();
if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
boolean newVal = isSeparateNotificationConfigEnabled();
if (newVal != mSeparateNotification) {
mSeparateNotification = newVal;
// Update UI if config change happens when Sound Settings page is on the foreground
if (mPreference != null) {
int status = getAvailabilityStatus();
mPreference.setVisible(status == AVAILABLE
|| status == DISABLED_DEPENDENT_SETTING);
if (status == DISABLED_DEPENDENT_SETTING) {
mPreference.setEnabled(false);
}
}
}
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@Override
public void onResume() {
super.onResume();
mReceiver.register(true);
Binder.withCleanCallingIdentity(()
-> DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
ActivityThread.currentApplication().getMainExecutor(), this::onDeviceConfigChange));
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
@@ -122,18 +90,13 @@ public class NotificationVolumePreferenceController extends
public void onPause() {
super.onPause();
mReceiver.register(false);
Binder.withCleanCallingIdentity(() ->
DeviceConfig.removeOnPropertiesChangedListener(this::onDeviceConfigChange));
}
@Override
public int getAvailabilityStatus() {
boolean separateNotification = isSeparateNotificationConfigEnabled();
return mContext.getResources().getBoolean(R.bool.config_show_notification_volume)
&& !mHelper.isSingleVolume() && separateNotification
? (mRingerMode == AudioManager.RINGER_MODE_NORMAL
? AVAILABLE : DISABLED_DEPENDENT_SETTING)
: UNSUPPORTED_ON_DEVICE;
&& !mHelper.isSingleVolume() ? (mRingerMode == AudioManager.RINGER_MODE_NORMAL
? AVAILABLE : DISABLED_DEPENDENT_SETTING) : UNSUPPORTED_ON_DEVICE;
}
@Override

View File

@@ -16,28 +16,22 @@
package com.android.settings.notification;
import android.app.ActivityThread;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.DeviceConfig;
import android.service.notification.NotificationListenerService;
import androidx.lifecycle.OnLifecycleEvent;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Set;
/**
* This slider represents both ring and notification
*/
@@ -61,33 +55,14 @@ public class RingVolumePreferenceController extends
mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
mSilentIconId = R.drawable.ic_notifications_off_24dp;
mSeparateNotification = isSeparateNotificationConfigEnabled();
updateRingerMode();
}
/**
* As the responsibility of this slider changes, so should its title & icon
*/
private void onDeviceConfigChange(DeviceConfig.Properties properties) {
Set<String> changeSet = properties.getKeyset();
if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
boolean valueUpdated = readSeparateNotificationVolumeConfig();
if (valueUpdated) {
updateEffectsSuppressor();
selectPreferenceIconState();
}
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@Override
public void onResume() {
super.onResume();
mReceiver.register(true);
readSeparateNotificationVolumeConfig();
Binder.withCleanCallingIdentity(()
-> DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
ActivityThread.currentApplication().getMainExecutor(), this::onDeviceConfigChange));
updateEffectsSuppressor();
selectPreferenceIconState();
@@ -101,8 +76,6 @@ public class RingVolumePreferenceController extends
public void onPause() {
super.onPause();
mReceiver.register(false);
Binder.withCleanCallingIdentity(() ->
DeviceConfig.removeOnPropertiesChangedListener(this::onDeviceConfigChange));
}
@Override
@@ -112,9 +85,7 @@ public class RingVolumePreferenceController extends
@Override
public int getAvailabilityStatus() {
boolean separateNotification = isSeparateNotificationConfigEnabled();
return !separateNotification && !mHelper.isSingleVolume()
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
return UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -124,14 +95,10 @@ public class RingVolumePreferenceController extends
@Override
protected boolean hintsMatch(int hints) {
boolean notificationSeparated = isSeparateNotificationConfigEnabled();
return (hints & NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS) != 0
|| (hints & NotificationListenerService.HINT_HOST_DISABLE_EFFECTS) != 0
|| ((hints & NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS)
!= 0 && !notificationSeparated);
|| (hints & NotificationListenerService.HINT_HOST_DISABLE_EFFECTS) != 0;
}
private final class H extends Handler {
private static final int UPDATE_EFFECTS_SUPPRESSOR = 1;
private static final int UPDATE_RINGER_MODE = 2;

View File

@@ -21,14 +21,11 @@ import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.media.AudioManager;
import android.os.Binder;
import android.os.ServiceManager;
import android.os.Vibrator;
import android.provider.DeviceConfig;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import java.util.Objects;
@@ -48,11 +45,8 @@ public abstract class RingerModeAffectedVolumePreferenceController extends
protected Vibrator mVibrator;
protected int mRingerMode = AudioManager.RINGER_MODE_NORMAL;
protected ComponentName mSuppressor;
protected boolean mSeparateNotification;
protected INotificationManager mNoMan;
private static final boolean CONFIG_SEPARATE_NOTIFICATION_DEFAULT_VAL = false;
public RingerModeAffectedVolumePreferenceController(Context context, String key, String tag) {
super(context, key);
mTag = tag;
@@ -118,28 +112,6 @@ public abstract class RingerModeAffectedVolumePreferenceController extends
return mMuteIcon;
}
protected boolean isSeparateNotificationConfigEnabled() {
return Binder.withCleanCallingIdentity(()
-> DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION,
CONFIG_SEPARATE_NOTIFICATION_DEFAULT_VAL));
}
/**
* side effect: updates the cached value of the config
* @return has the config changed?
*/
protected boolean readSeparateNotificationVolumeConfig() {
boolean newVal = isSeparateNotificationConfigEnabled();
boolean valueUpdated = newVal != mSeparateNotification;
if (valueUpdated) {
mSeparateNotification = newVal;
}
return valueUpdated;
}
/**
* Updates UI Icon in response to ringer mode changes.
* @return whether the ringer mode has changed.

View File

@@ -16,7 +16,6 @@
package com.android.settings.notification;
import android.app.ActivityThread;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -26,17 +25,13 @@ import android.media.AudioManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.DeviceConfig;
import android.service.notification.NotificationListenerService;
import androidx.lifecycle.OnLifecycleEvent;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Set;
/**
* This slider is used to represent ring volume when ring is separated from notification
*/
@@ -60,32 +55,14 @@ public class SeparateRingVolumePreferenceController extends
mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
mSilentIconId = R.drawable.ic_ring_volume_off;
mSeparateNotification = isSeparateNotificationConfigEnabled();
updateRingerMode();
}
/**
* Show/hide settings
*/
private void onDeviceConfigChange(DeviceConfig.Properties properties) {
Set<String> changeSet = properties.getKeyset();
if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
boolean valueUpdated = readSeparateNotificationVolumeConfig();
if (valueUpdated) {
updateEffectsSuppressor();
selectPreferenceIconState();
}
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@Override
public void onResume() {
super.onResume();
mReceiver.register(true);
readSeparateNotificationVolumeConfig();
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
ActivityThread.currentApplication().getMainExecutor(), this::onDeviceConfigChange);
updateEffectsSuppressor();
selectPreferenceIconState();
@@ -99,7 +76,6 @@ public class SeparateRingVolumePreferenceController extends
public void onPause() {
super.onPause();
mReceiver.register(false);
DeviceConfig.removeOnPropertiesChangedListener(this::onDeviceConfigChange);
}
@Override
@@ -109,9 +85,7 @@ public class SeparateRingVolumePreferenceController extends
@Override
public int getAvailabilityStatus() {
boolean separateNotification = isSeparateNotificationConfigEnabled();
return separateNotification && !mHelper.isSingleVolume()
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
return !mHelper.isSingleVolume() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -125,8 +99,6 @@ public class SeparateRingVolumePreferenceController extends
|| (hints & NotificationListenerService.HINT_HOST_DISABLE_EFFECTS) != 0;
}
private final class H extends Handler {
private static final int UPDATE_EFFECTS_SUPPRESSOR = 1;
private static final int UPDATE_RINGER_MODE = 2;

View File

@@ -196,7 +196,6 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult
ArrayList<VolumeSeekBarPreferenceController> volumeControllers = new ArrayList<>();
volumeControllers.add(use(AlarmVolumePreferenceController.class));
volumeControllers.add(use(MediaVolumePreferenceController.class));
volumeControllers.add(use(RingVolumePreferenceController.class));
volumeControllers.add(use(SeparateRingVolumePreferenceController.class));
volumeControllers.add(use(NotificationVolumePreferenceController.class));
volumeControllers.add(use(CallVolumePreferenceController.class));

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2023 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.deviceinfo.batteryinfo;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class BatteryCycleCountPreferenceControllerTest {
private BatteryCycleCountPreferenceController mController;
private Context mContext;
@Before
public void setUp() {
mContext = spy(ApplicationProvider.getApplicationContext());
mController = new BatteryCycleCountPreferenceController(mContext,
"battery_info_cycle_count");
}
@Test
public void getAvailabilityStatus_returnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getSummary_returnExpectedResult() {
final Intent batteryIntent = new Intent();
batteryIntent.putExtra(BatteryManager.EXTRA_CYCLE_COUNT, 10);
doReturn(batteryIntent).when(mContext).registerReceiver(any(), any());
assertThat(mController.getSummary()).isEqualTo("10");
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2023 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.deviceinfo.batteryinfo;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class BatteryFirstUseDatePreferenceControllerTest {
private BatteryFirstUseDatePreferenceController mController;
private Context mContext;
private FakeFeatureFactory mFactory;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mFactory = FakeFeatureFactory.setupForTest();
mController = new BatteryFirstUseDatePreferenceController(mContext,
"battery_info_first_use_date");
}
@Test
public void getAvailabilityStatus_dateAvailable_returnAvailable() {
when(mFactory.mBatteryInfoFeatureProvider.isFirstUseDateAvailable()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_dateUnavailable_returnNotAvailable() {
when(mFactory.mBatteryInfoFeatureProvider.isFirstUseDateAvailable()).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2023 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.deviceinfo.batteryinfo;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class BatteryManufactureDatePreferenceControllerTest {
private BatteryManufactureDatePreferenceController mController;
private Context mContext;
private FakeFeatureFactory mFactory;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mFactory = FakeFeatureFactory.setupForTest();
mController = new BatteryManufactureDatePreferenceController(mContext,
"battery_info_manufacture_date");
}
@Test
public void getAvailabilityStatus_dateAvailable_returnAvailable() {
when(mFactory.mBatteryInfoFeatureProvider.isManufactureDateAvailable()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_dateUnavailable_returnNotAvailable() {
when(mFactory.mBatteryInfoFeatureProvider.isManufactureDateAvailable()).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -18,7 +18,6 @@ package com.android.settings.notification;
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;
@@ -26,15 +25,11 @@ import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Vibrator;
import android.provider.DeviceConfig;
import android.service.notification.NotificationListenerService;
import android.telephony.TelephonyManager;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
@@ -45,7 +40,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@@ -64,9 +58,6 @@ public class NotificationVolumePreferenceControllerTest {
@Mock
private PreferenceManager mPreferenceManager;
private static final String READ_DEVICE_CONFIG_PERMISSION =
"android.permission.READ_DEVICE_CONFIG";
private Context mContext;
private NotificationVolumePreferenceController mController;
@@ -97,34 +88,15 @@ public class NotificationVolumePreferenceControllerTest {
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_voiceCapable_aliasedWithRing_shouldReturnFalse() {
when(mResources.getBoolean(
com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
NotificationVolumePreferenceController controller =
new NotificationVolumePreferenceController(mContext);
when(mHelper.isSingleVolume()).thenReturn(false);
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
assertThat(controller.isAvailable()).isFalse();
}
/**
* With the introduction of ring-notification volume separation, voice-capable devices could now
* display the notification volume slider.
*/
@Test
public void isAvailable_voiceCapable_separatedFromRing_shouldReturnTrue() {
public void isAvailable_whenVoiceCapable_shouldReturnTrue() {
when(mResources.getBoolean(
com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
NotificationVolumePreferenceController controller =
new NotificationVolumePreferenceController(mContext);
@@ -189,84 +161,13 @@ public class NotificationVolumePreferenceControllerTest {
}
@Test
public void enableSeparateNotificationConfig_controllerBecomesAvailable() {
PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
VolumeSeekBarPreference volumeSeekBarPreference = mock(VolumeSeekBarPreference.class);
when(screen.getPreferenceManager()).thenReturn(mPreferenceManager);
when(screen.getContext()).thenReturn(mContext);
when(mResources.getBoolean(
com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
// block the alternative condition to enable controller
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
NotificationVolumePreferenceController controller =
new NotificationVolumePreferenceController(mContext);
when(screen.findPreference(controller.getPreferenceKey()))
.thenReturn(volumeSeekBarPreference);
// allow the controller to subscribe
Shadows.shadowOf((android.app.Application) ApplicationProvider.getApplicationContext())
.grantPermissions(READ_DEVICE_CONFIG_PERMISSION);
controller.onResume();
controller.displayPreference(screen);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, Boolean.toString(true),
false);
assertThat(controller.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void disableSeparateNotificationConfig_controllerBecomesUnavailable() {
PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
VolumeSeekBarPreference volumeSeekBarPreference = mock(VolumeSeekBarPreference.class);
when(screen.getPreferenceManager()).thenReturn(mPreferenceManager);
when(screen.getContext()).thenReturn(mContext);
when(mResources.getBoolean(
com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
// block the alternative condition to enable controller
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
NotificationVolumePreferenceController controller =
new NotificationVolumePreferenceController(mContext);
when(screen.findPreference(controller.getPreferenceKey()))
.thenReturn(volumeSeekBarPreference);
Shadows.shadowOf((android.app.Application) ApplicationProvider.getApplicationContext())
.grantPermissions(READ_DEVICE_CONFIG_PERMISSION);
controller.onResume();
controller.displayPreference(screen);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
assertThat(controller.getAvailabilityStatus()
== BasePreferenceController.UNSUPPORTED_ON_DEVICE).isTrue();
}
@Test
public void ringerModeSilent_unaliased_getAvailability_returnsDisabled() {
public void ringerModeSilent_getAvailability_returnsDisabled() {
when(mResources.getBoolean(
com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
when(mHelper.isSingleVolume()).thenReturn(false);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING);
}

View File

@@ -27,11 +27,9 @@ import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Vibrator;
import android.provider.DeviceConfig;
import android.service.notification.NotificationListenerService;
import android.telephony.TelephonyManager;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
@@ -83,9 +81,6 @@ public class RingVolumePreferenceControllerTest {
when(mContext.getResources()).thenReturn(mResources);
mController = new RingVolumePreferenceController(mContext);
mController.setAudioHelper(mHelper);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
}
@Test
@@ -110,7 +105,6 @@ public class RingVolumePreferenceControllerTest {
@Test
public void isAvailable_notSingleVolume_VoiceCapable_shouldReturnTrue() {
when(mHelper.isSingleVolume()).thenReturn(false);
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
@@ -139,10 +133,6 @@ public class RingVolumePreferenceControllerTest {
*/
@Test
public void ringNotificationStreamsSeparate_controllerIsNotAvailable() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
final RingVolumePreferenceController controller =
new RingVolumePreferenceController(mContext);
@@ -153,58 +143,19 @@ public class RingVolumePreferenceControllerTest {
}
@Test
public void setHintsRing_aliased_Matches() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
public void setHintsRing_Matches() {
assertThat(mController.hintsMatch(
NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS)).isTrue();
}
@Test
public void setHintsRingNotification_aliased_Matches() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
public void setHintsRingNotification_Matches() {
assertThat(mController.hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_EFFECTS))
.isTrue();
}
@Test
public void setHintNotification_aliased_Matches() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
assertThat(mController
.hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS))
.isTrue();
}
@Test
public void setHintsRing_unaliased_Matches() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
assertThat(mController.hintsMatch(
NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS)).isTrue();
}
@Test
public void setHintsRingNotification_unaliased_Matches() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
assertThat(mController.hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_EFFECTS))
.isTrue();
}
@Test
public void setHintNotification_unaliased_doesNotMatch() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
public void setHintNotification_doesNotMatch() {
assertThat(mController
.hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS))
.isFalse();

View File

@@ -27,10 +27,8 @@ import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Vibrator;
import android.provider.DeviceConfig;
import android.telephony.TelephonyManager;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import org.junit.Before;
@@ -81,21 +79,11 @@ public class SeparateRingVolumePreferenceControllerTest {
mController.setAudioHelper(mHelper);
}
@Test
public void isAvailable_ringNotificationAliased_shouldReturnFalse() {
when(mHelper.isSingleVolume()).thenReturn(true);
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
assertThat(mController.isAvailable()).isFalse();
}
/**
* Maintain that the device does not need to be voice capable to display this slider
*/
@Test
public void isAvailable_ringNotificationSeparated_isNotVoiceCapable_shouldReturnTrue() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
public void isAvailable_whenNotVoiceCapable_shouldReturnTrue() {
when(mHelper.isSingleVolume()).thenReturn(false);
when(mTelephonyManager.isVoiceCapable()).thenReturn(false);

View File

@@ -69,7 +69,7 @@ public class SoundSettingsTest {
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.zen_mode_settings));
// Add keys with hidden resources
keys.add("alarm_volume");
keys.add("ring_volume");
keys.add("separate_ring_volume");
keys.add("notification_volume");
assertThat(keys).containsAtLeastElementsIn(niks);
@@ -93,7 +93,7 @@ public class SoundSettingsTest {
final int xmlId = settings.getPreferenceScreenResId();
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
int ring = keys.indexOf("ring_volume");
int ring = keys.indexOf("separate_ring_volume");
int notification = keys.indexOf("notification_volume");
int alarm = keys.indexOf("alarm_volume");

View File

@@ -16,6 +16,8 @@
package com.android.settings.bluetooth;
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -24,8 +26,8 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.PendingIntent;
import android.content.Context;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -42,20 +44,20 @@ import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.bluetooth.BlockingPrefWithSliceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@RunWith(AndroidJUnit4.class)
public class BlockingPrefWithSliceControllerTest {
private static final String KEY = "bt_device_slice_category";
private static final String TEST_URI_AUTHORITY = "com.android.authority.test";
private static final String TEST_URI_AUTHORITY = "com.android.settings";
private static final String TEST_EXTRA_INTENT = "EXTRA_INTENT";
private static final String TEST_EXTRA_PENDING_INTENT = "EXTRA_PENDING_INTENT";
private static final String TEST_INTENT_ACTION = "test";
@@ -71,6 +73,8 @@ public class BlockingPrefWithSliceControllerTest {
private LiveData<Slice> mLiveData;
@Mock
private PreferenceCategory mPreferenceCategory;
@Captor
ArgumentCaptor<Preference> mPreferenceArgumentCaptor;
private Context mContext;
private BlockingPrefWithSliceController mController;
@@ -130,6 +134,14 @@ public class BlockingPrefWithSliceControllerTest {
verify(mController.mPreferenceCategory).addPreference(any());
}
@Test
public void onChanged_sliceWithoutValidIntent_makePreferenceUnselectable() {
mController.onChanged(buildTestSlice());
verify(mController.mPreferenceCategory).addPreference(mPreferenceArgumentCaptor.capture());
assertThat(mPreferenceArgumentCaptor.getValue().isSelectable()).isFalse();
}
private Slice buildTestSlice() {
Uri uri =
new Uri.Builder()
@@ -141,7 +153,7 @@ public class BlockingPrefWithSliceControllerTest {
IconCompat icon = mock(IconCompat.class);
listBuilder.addRow(
new RowBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
.setTitleItem(icon, ICON_IMAGE)
.setTitle(TEST_SLICE_TITLE)
.setSubtitle(TEST_SLICE_SUBTITLE)
.setPrimaryAction(
@@ -153,7 +165,7 @@ public class BlockingPrefWithSliceControllerTest {
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_IMMUTABLE),
icon,
ListBuilder.ICON_IMAGE,
ICON_IMAGE,
"")));
return listBuilder.build();
}