Snap for 12923841 from e8f5daaf88 to 25Q2-release
Change-Id: Ife4f556f3ae26a65f47fb33ad8c264225d9f6c9d
This commit is contained in:
@@ -5271,7 +5271,7 @@
|
|||||||
android:permission="android.permission.MASTER_CLEAR"
|
android:permission="android.permission.MASTER_CLEAR"
|
||||||
android:label="@string/main_clear_title"
|
android:label="@string/main_clear_title"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/SudThemeGlif.Light">
|
android:theme="@style/SettingsSudThemeGlif.Light">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.android.settings.action.FACTORY_RESET"/>
|
<action android:name="com.android.settings.action.FACTORY_RESET"/>
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
@@ -5285,7 +5285,7 @@
|
|||||||
<activity android:name="Settings$FactoryResetConfirmActivity"
|
<activity android:name="Settings$FactoryResetConfirmActivity"
|
||||||
android:label="@string/main_clear_confirm_title"
|
android:label="@string/main_clear_confirm_title"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:theme="@style/SudThemeGlif.Light">
|
android:theme="@style/SettingsSudThemeGlif.Light">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
package: "com.android.settings.development"
|
package: "com.android.settings.development"
|
||||||
container: "system"
|
container: "system"
|
||||||
|
|
||||||
flag {
|
|
||||||
name: "a2dp_offload_codec_extensibility_settings"
|
|
||||||
namespace: "bluetooth"
|
|
||||||
description: "Feature flag for Bluetooth Audio Codec extensibility in Settings"
|
|
||||||
bug: "323319530"
|
|
||||||
}
|
|
||||||
|
|
||||||
flag {
|
flag {
|
||||||
name: "deprecate_list_activity"
|
name: "deprecate_list_activity"
|
||||||
namespace: "android_settings"
|
namespace: "android_settings"
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2019 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="8dp">
|
|
||||||
|
|
||||||
<RadioGroup
|
|
||||||
android:id="@+id/bluetooth_audio_codec_radio_group"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/developer_option_dialog_margin_start">
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_default"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_sbc"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_aac"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_aptx"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_aptx_hd"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_ldac"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_lc3"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_opus"
|
|
||||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
|
||||||
|
|
||||||
</RadioGroup>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/bluetooth_audio_codec_help_info"
|
|
||||||
layout="@layout/preference_widget_dialog_summary"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@
|
|||||||
<!-- Homepage should follow device default design, the values is same as device default theme.-->
|
<!-- Homepage should follow device default design, the values is same as device default theme.-->
|
||||||
<item name="android:navigationBarColor">@android:color/white</item>
|
<item name="android:navigationBarColor">@android:color/white</item>
|
||||||
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
|
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
|
||||||
<item name="android:colorBackground">@android:color/system_surface_container_light</item>
|
<item name="android:colorBackground">@color/settingslib_materialColorSurfaceContainerLow</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.Settings.Home.NoAnimation">
|
<style name="Theme.Settings.Home.NoAnimation">
|
||||||
@@ -247,4 +247,8 @@
|
|||||||
<item name="colorPrimary">@*android:color/primary_device_default_settings_light</item>
|
<item name="colorPrimary">@*android:color/primary_device_default_settings_light</item>
|
||||||
<item name="colorAccent">@*android:color/accent_device_default_light</item>
|
<item name="colorAccent">@*android:color/accent_device_default_light</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="SettingsSudThemeGlif.Light" parent="@style/SudThemeGlif.Light">
|
||||||
|
<item name="android:background">@color/settingslib_materialColorSurfaceContainerLowest</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -434,14 +434,6 @@
|
|||||||
android:key="bluetooth_hd_audio_settings"
|
android:key="bluetooth_hd_audio_settings"
|
||||||
android:title="@string/bluetooth_profile_a2dp_high_quality_unknown_codec"/>
|
android:title="@string/bluetooth_profile_a2dp_high_quality_unknown_codec"/>
|
||||||
|
|
||||||
<com.android.settings.development.bluetooth.BluetoothCodecDialogPreference
|
|
||||||
android:key="bluetooth_audio_codec_settings"
|
|
||||||
android:title="@string/bluetooth_select_a2dp_codec_type"
|
|
||||||
android:dialogTitle="@string/bluetooth_select_a2dp_codec_type_dialog_title"
|
|
||||||
android:dialogLayout="@layout/bluetooth_audio_codec_dialog"
|
|
||||||
android:positiveButtonText=""
|
|
||||||
android:negativeButtonText="@string/dlg_ok"/>
|
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="bluetooth_audio_codec_settings_list"
|
android:key="bluetooth_audio_codec_settings_list"
|
||||||
android:title="@string/bluetooth_select_a2dp_codec_type"
|
android:title="@string/bluetooth_select_a2dp_codec_type"
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class HighContrastTextMigrationReceiver extends BroadcastReceiver {
|
|||||||
static final String ACTION_OPEN_SETTINGS =
|
static final String ACTION_OPEN_SETTINGS =
|
||||||
"com.android.settings.accessibility.ACTION_OPEN_HIGH_CONTRAST_TEXT_SETTINGS";
|
"com.android.settings.accessibility.ACTION_OPEN_HIGH_CONTRAST_TEXT_SETTINGS";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int NOTIFICATION_ID = 1;
|
static final int NOTIFICATION_ID = R.string.accessibility_notification_high_contrast_text_title;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({
|
@IntDef({
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.connecteddevice.audiosharing;
|
package com.android.settings.connecteddevice.audiosharing;
|
||||||
|
|
||||||
|
import static com.android.settingslib.Utils.isAudioModeOngoingCall;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothCsipSetCoordinator;
|
import android.bluetooth.BluetoothCsipSetCoordinator;
|
||||||
@@ -48,6 +50,7 @@ import com.android.settingslib.bluetooth.BluetoothEventManager;
|
|||||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||||
|
import com.android.settingslib.bluetooth.LeAudioProfile;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||||
@@ -91,6 +94,7 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP
|
|||||||
Map<Integer, List<BluetoothDevice>> mGroupedConnectedDevices = new HashMap<>();
|
Map<Integer, List<BluetoothDevice>> mGroupedConnectedDevices = new HashMap<>();
|
||||||
private List<AudioSharingDeviceItem> mDeviceItemsInSharingSession = new ArrayList<>();
|
private List<AudioSharingDeviceItem> mDeviceItemsInSharingSession = new ArrayList<>();
|
||||||
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
|
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
|
||||||
|
private AtomicBoolean mIsAudioModeOngoingCall = new AtomicBoolean(false);
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
||||||
@@ -202,28 +206,15 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP
|
|||||||
mDeviceItemsInSharingSession,
|
mDeviceItemsInSharingSession,
|
||||||
pair == null ? -1 : pair.first,
|
pair == null ? -1 : pair.first,
|
||||||
(AudioSharingDeviceItem item) -> {
|
(AudioSharingDeviceItem item) -> {
|
||||||
int currentGroupId =
|
int currentCallAudioGroupId =
|
||||||
BluetoothUtils.getPrimaryGroupIdForBroadcast(
|
BluetoothUtils.getPrimaryGroupIdForBroadcast(
|
||||||
mContext.getContentResolver());
|
mContext.getContentResolver());
|
||||||
int clickedGroupId = item.getGroupId();
|
int clickedGroupId = item.getGroupId();
|
||||||
if (clickedGroupId == currentGroupId) {
|
if (clickedGroupId == currentCallAudioGroupId) {
|
||||||
Log.d(TAG, "Skip set call audio device: unchanged");
|
Log.d(TAG, "Skip set call audio device: unchanged");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<BluetoothDevice> devices =
|
setCallAudioGroup(clickedGroupId);
|
||||||
mGroupedConnectedDevices.getOrDefault(
|
|
||||||
clickedGroupId, ImmutableList.of());
|
|
||||||
CachedBluetoothDevice lead =
|
|
||||||
AudioSharingUtils.getLeadDevice(
|
|
||||||
mCacheManager, devices);
|
|
||||||
if (lead != null) {
|
|
||||||
String addr = lead.getDevice().getAnonymizedAddress();
|
|
||||||
Log.d(TAG, "Set call audio device: " + addr);
|
|
||||||
AudioSharingUtils.setPrimary(mContext, lead);
|
|
||||||
logCallAudioDeviceChange(currentGroupId, lead);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Skip set call audio device: no lead");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -269,6 +260,11 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioModeChanged() {
|
||||||
|
mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the controller.
|
* Initialize the controller.
|
||||||
*
|
*
|
||||||
@@ -311,6 +307,7 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP
|
|||||||
false,
|
false,
|
||||||
mSettingsObserver);
|
mSettingsObserver);
|
||||||
mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
|
mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
|
||||||
|
mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext));
|
||||||
mCallbacksRegistered.set(true);
|
mCallbacksRegistered.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,6 +330,32 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setCallAudioGroup(int groupId) {
|
||||||
|
List<BluetoothDevice> devices =
|
||||||
|
mGroupedConnectedDevices.getOrDefault(
|
||||||
|
groupId, ImmutableList.of());
|
||||||
|
CachedBluetoothDevice lead =
|
||||||
|
AudioSharingUtils.getLeadDevice(
|
||||||
|
mCacheManager, devices);
|
||||||
|
if (lead != null) {
|
||||||
|
String addr = lead.getDevice().getAnonymizedAddress();
|
||||||
|
Log.d(TAG, "Set call audio device: " + addr);
|
||||||
|
if (Flags.adoptPrimaryGroupManagementApi() && !mIsAudioModeOngoingCall.get()) {
|
||||||
|
LeAudioProfile leaProfile = mBtManager == null ? null
|
||||||
|
: mBtManager.getProfileManager().getLeAudioProfile();
|
||||||
|
if (leaProfile != null) {
|
||||||
|
leaProfile.setBroadcastToUnicastFallbackGroup(groupId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lead.setActive();
|
||||||
|
}
|
||||||
|
AudioSharingUtils.setUserPreferredPrimary(mContext, lead);
|
||||||
|
logCallAudioDeviceChange(groupId, lead);
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Skip set call audio device: no lead");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the preference summary: current headset for call audio.
|
* Update the preference summary: current headset for call audio.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -389,7 +389,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
|
|||||||
Log.d(TAG, "onDeviceClick, set active in call mode");
|
Log.d(TAG, "onDeviceClick, set active in call mode");
|
||||||
CachedBluetoothDevice cachedDevice =
|
CachedBluetoothDevice cachedDevice =
|
||||||
((BluetoothDevicePreference) preference).getBluetoothDevice();
|
((BluetoothDevicePreference) preference).getBluetoothDevice();
|
||||||
AudioSharingUtils.setPrimary(mContext, cachedDevice);
|
cachedDevice.setActive();
|
||||||
|
AudioSharingUtils.setUserPreferredPrimary(mContext, cachedDevice);
|
||||||
}
|
}
|
||||||
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK,
|
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK,
|
||||||
isCallMode);
|
isCallMode);
|
||||||
|
|||||||
@@ -192,7 +192,8 @@ public class AudioSharingDialogHandler {
|
|||||||
// If this method is called with user triggered, e.g. manual click on the
|
// If this method is called with user triggered, e.g. manual click on the
|
||||||
// "Connected devices" page, we need call setActive for the device, since user
|
// "Connected devices" page, we need call setActive for the device, since user
|
||||||
// intend to switch active device for the call.
|
// intend to switch active device for the call.
|
||||||
AudioSharingUtils.setPrimary(mContext, cachedDevice);
|
cachedDevice.setActive();
|
||||||
|
AudioSharingUtils.setUserPreferredPrimary(mContext, cachedDevice);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,11 +346,10 @@ public class AudioSharingUtils {
|
|||||||
return vc != null && vc.isProfileReady();
|
return vc != null && vc.isProfileReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set {@link CachedBluetoothDevice} as primary device for call audio */
|
/** Set {@link CachedBluetoothDevice} as user preferred primary device for call audio */
|
||||||
public static void setPrimary(
|
public static void setUserPreferredPrimary(
|
||||||
@NonNull Context context, @Nullable CachedBluetoothDevice cachedDevice) {
|
@NonNull Context context, @Nullable CachedBluetoothDevice cachedDevice) {
|
||||||
if (cachedDevice == null) return;
|
if (cachedDevice == null) return;
|
||||||
cachedDevice.setActive();
|
|
||||||
if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(context)) {
|
if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(context)) {
|
||||||
int groupId = BluetoothUtils.getGroupId(cachedDevice);
|
int groupId = BluetoothUtils.getGroupId(cachedDevice);
|
||||||
// TODO: use real key name in SettingsProvider
|
// TODO: use real key name in SettingsProvider
|
||||||
|
|||||||
@@ -1,225 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.development;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothA2dp;
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
|
||||||
import android.bluetooth.BluetoothCodecConfig;
|
|
||||||
import android.bluetooth.BluetoothCodecStatus;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.bluetooth.BluetoothManager;
|
|
||||||
import android.bluetooth.BluetoothProfile;
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
import androidx.preference.ListPreference;
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
|
||||||
import com.android.settingslib.core.lifecycle.events.OnDestroy;
|
|
||||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class AbstractBluetoothA2dpPreferenceController extends
|
|
||||||
DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
|
|
||||||
PreferenceControllerMixin, BluetoothServiceConnectionListener, LifecycleObserver,
|
|
||||||
OnDestroy {
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
static final int STREAMING_LABEL_ID =
|
|
||||||
com.android.settingslib.R.string.bluetooth_select_a2dp_codec_streaming_label;
|
|
||||||
|
|
||||||
protected final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore;
|
|
||||||
protected BluetoothA2dp mBluetoothA2dp;
|
|
||||||
protected ListPreference mPreference;
|
|
||||||
private final String[] mListValues;
|
|
||||||
private final String[] mListSummaries;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
BluetoothAdapter mBluetoothAdapter;
|
|
||||||
|
|
||||||
public AbstractBluetoothA2dpPreferenceController(Context context, Lifecycle lifecycle,
|
|
||||||
BluetoothA2dpConfigStore store) {
|
|
||||||
super(context);
|
|
||||||
|
|
||||||
mBluetoothA2dpConfigStore = store;
|
|
||||||
mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
|
|
||||||
mListValues = getListValues();
|
|
||||||
mListSummaries = getListSummaries();
|
|
||||||
|
|
||||||
if (lifecycle != null) {
|
|
||||||
lifecycle.addObserver(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void displayPreference(PreferenceScreen screen) {
|
|
||||||
super.displayPreference(screen);
|
|
||||||
|
|
||||||
mPreference = screen.findPreference(getPreferenceKey());
|
|
||||||
|
|
||||||
// Set a default value because BluetoothCodecConfig is null initially.
|
|
||||||
mPreference.setValue(mListValues[getDefaultIndex()]);
|
|
||||||
mPreference.setSummary(mListSummaries[getDefaultIndex()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
if (mBluetoothA2dp == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeConfigurationValues(newValue);
|
|
||||||
|
|
||||||
final BluetoothCodecConfig codecConfig = mBluetoothA2dpConfigStore.createCodecConfig();
|
|
||||||
synchronized (mBluetoothA2dpConfigStore) {
|
|
||||||
BluetoothDevice activeDevice = getA2dpActiveDevice();
|
|
||||||
if (activeDevice == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
setCodecConfigPreference(activeDevice, codecConfig);
|
|
||||||
}
|
|
||||||
// Because the setting is not persisted into permanent storage, we cannot call update state
|
|
||||||
// here to update the preference.
|
|
||||||
// Instead, we just assume it was set and update the preference here.
|
|
||||||
final int index = mPreference.findIndexOfValue(newValue.toString());
|
|
||||||
// We only want to append "Streaming" if not using default
|
|
||||||
if (index == getDefaultIndex()) {
|
|
||||||
mPreference.setSummary(mListSummaries[index]);
|
|
||||||
} else {
|
|
||||||
mPreference.setSummary(
|
|
||||||
mContext.getResources().getString(STREAMING_LABEL_ID, mListSummaries[index]));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateState(Preference preference) {
|
|
||||||
BluetoothDevice activeDevice = getA2dpActiveDevice();
|
|
||||||
if (activeDevice == null || getCodecConfig(activeDevice) == null || mPreference == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BluetoothCodecConfig codecConfig;
|
|
||||||
synchronized (mBluetoothA2dpConfigStore) {
|
|
||||||
codecConfig = getCodecConfig(activeDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int index = getCurrentA2dpSettingIndex(codecConfig);
|
|
||||||
mPreference.setValue(mListValues[index]);
|
|
||||||
|
|
||||||
// We only want to append "Streaming" if not using default
|
|
||||||
if (index == getDefaultIndex()) {
|
|
||||||
mPreference.setSummary(mListSummaries[index]);
|
|
||||||
} else {
|
|
||||||
mPreference.setSummary(
|
|
||||||
mContext.getResources().getString(STREAMING_LABEL_ID, mListSummaries[index]));
|
|
||||||
}
|
|
||||||
|
|
||||||
writeConfigurationValues(mListValues[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBluetoothServiceConnected(BluetoothA2dp bluetoothA2dp) {
|
|
||||||
mBluetoothA2dp = bluetoothA2dp;
|
|
||||||
updateState(mPreference);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBluetoothCodecUpdated() {
|
|
||||||
// intentional no-op
|
|
||||||
// We do not want to call update state here because the setting is not persisted in
|
|
||||||
// permanent storage.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBluetoothServiceDisconnected() {
|
|
||||||
mBluetoothA2dp = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
mBluetoothA2dp = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return an array of string values that correspond to the current {@link ListPreference}.
|
|
||||||
*/
|
|
||||||
protected abstract String[] getListValues();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return an array of string summaries that correspond to the current {@link ListPreference}.
|
|
||||||
*/
|
|
||||||
protected abstract String[] getListSummaries();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the new value to the {@link BluetoothA2dpConfigStore} and the {@link BluetoothA2dp}.
|
|
||||||
*
|
|
||||||
* @param newValue the new setting value
|
|
||||||
*/
|
|
||||||
protected abstract void writeConfigurationValues(Object newValue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the current selected index for the {@link ListPreference}.
|
|
||||||
*/
|
|
||||||
protected abstract int getCurrentA2dpSettingIndex(BluetoothCodecConfig config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return default setting index for the {@link ListPreference}.
|
|
||||||
*/
|
|
||||||
protected abstract int getDefaultIndex();
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void setCodecConfigPreference(BluetoothDevice device,
|
|
||||||
BluetoothCodecConfig config) {
|
|
||||||
BluetoothDevice bluetoothDevice =
|
|
||||||
(device != null) ? device : getA2dpActiveDevice();
|
|
||||||
if (bluetoothDevice == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mBluetoothA2dp.setCodecConfigPreference(bluetoothDevice, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
BluetoothCodecConfig getCodecConfig(BluetoothDevice device) {
|
|
||||||
if (mBluetoothA2dp != null) {
|
|
||||||
BluetoothDevice bluetoothDevice =
|
|
||||||
(device != null) ? device : getA2dpActiveDevice();
|
|
||||||
if (bluetoothDevice == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BluetoothCodecStatus codecStatus = mBluetoothA2dp.getCodecStatus(bluetoothDevice);
|
|
||||||
if (codecStatus != null) {
|
|
||||||
return codecStatus.getCodecConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BluetoothDevice getA2dpActiveDevice() {
|
|
||||||
if (mBluetoothAdapter == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
List<BluetoothDevice> activeDevices =
|
|
||||||
mBluetoothAdapter.getActiveDevices(BluetoothProfile.A2DP);
|
|
||||||
return (activeDevices.size() > 0) ? activeDevices.get(0) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,11 +16,9 @@
|
|||||||
|
|
||||||
package com.android.settings.development;
|
package com.android.settings.development;
|
||||||
|
|
||||||
import android.annotation.FlaggedApi;
|
|
||||||
import android.bluetooth.BluetoothCodecConfig;
|
import android.bluetooth.BluetoothCodecConfig;
|
||||||
import android.bluetooth.BluetoothCodecType;
|
import android.bluetooth.BluetoothCodecType;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
/** Utility class for storing current Bluetooth A2DP profile values */
|
/** Utility class for storing current Bluetooth A2DP profile values */
|
||||||
@@ -38,10 +36,6 @@ public class BluetoothA2dpConfigStore {
|
|||||||
private long mCodecSpecific3Value;
|
private long mCodecSpecific3Value;
|
||||||
private long mCodecSpecific4Value;
|
private long mCodecSpecific4Value;
|
||||||
|
|
||||||
public void setCodecType(int codecType) {
|
|
||||||
mCodecTypeNative = codecType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCodecType(@Nullable BluetoothCodecType codecType) {
|
public void setCodecType(@Nullable BluetoothCodecType codecType) {
|
||||||
mCodecType = codecType;
|
mCodecType = codecType;
|
||||||
}
|
}
|
||||||
@@ -82,6 +76,7 @@ public class BluetoothA2dpConfigStore {
|
|||||||
public BluetoothCodecConfig createCodecConfig() {
|
public BluetoothCodecConfig createCodecConfig() {
|
||||||
BluetoothCodecConfig.Builder builder = new BluetoothCodecConfig.Builder()
|
BluetoothCodecConfig.Builder builder = new BluetoothCodecConfig.Builder()
|
||||||
.setCodecPriority(mCodecPriority)
|
.setCodecPriority(mCodecPriority)
|
||||||
|
.setExtendedCodecType(mCodecType)
|
||||||
.setSampleRate(mSampleRate)
|
.setSampleRate(mSampleRate)
|
||||||
.setBitsPerSample(mBitsPerSample)
|
.setBitsPerSample(mBitsPerSample)
|
||||||
.setChannelMode(mChannelMode)
|
.setChannelMode(mChannelMode)
|
||||||
@@ -89,27 +84,6 @@ public class BluetoothA2dpConfigStore {
|
|||||||
.setCodecSpecific2(mCodecSpecific2Value)
|
.setCodecSpecific2(mCodecSpecific2Value)
|
||||||
.setCodecSpecific3(mCodecSpecific3Value)
|
.setCodecSpecific3(mCodecSpecific3Value)
|
||||||
.setCodecSpecific4(mCodecSpecific4Value);
|
.setCodecSpecific4(mCodecSpecific4Value);
|
||||||
if (Flags.a2dpOffloadCodecExtensibilitySettings()) {
|
|
||||||
builder.setExtendedCodecType(mCodecType);
|
|
||||||
} else {
|
|
||||||
builder.setCodecType(mCodecTypeNative);
|
|
||||||
}
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create codec config utilizing {@link BluetoothCodecType} */
|
|
||||||
@FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
|
||||||
public @NonNull BluetoothCodecConfig createCodecConfigFromCodecType() {
|
|
||||||
return new BluetoothCodecConfig.Builder()
|
|
||||||
.setExtendedCodecType(mCodecType)
|
|
||||||
.setCodecPriority(mCodecPriority)
|
|
||||||
.setSampleRate(mSampleRate)
|
|
||||||
.setBitsPerSample(mBitsPerSample)
|
|
||||||
.setChannelMode(mChannelMode)
|
|
||||||
.setCodecSpecific1(mCodecSpecific1Value)
|
|
||||||
.setCodecSpecific2(mCodecSpecific2Value)
|
|
||||||
.setCodecSpecific3(mCodecSpecific3Value)
|
|
||||||
.setCodecSpecific4(mCodecSpecific4Value)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ import com.android.settings.development.bluetooth.AbstractBluetoothDialogPrefere
|
|||||||
import com.android.settings.development.bluetooth.AbstractBluetoothPreferenceController;
|
import com.android.settings.development.bluetooth.AbstractBluetoothPreferenceController;
|
||||||
import com.android.settings.development.bluetooth.BluetoothBitPerSampleDialogPreferenceController;
|
import com.android.settings.development.bluetooth.BluetoothBitPerSampleDialogPreferenceController;
|
||||||
import com.android.settings.development.bluetooth.BluetoothChannelModeDialogPreferenceController;
|
import com.android.settings.development.bluetooth.BluetoothChannelModeDialogPreferenceController;
|
||||||
import com.android.settings.development.bluetooth.BluetoothCodecDialogPreferenceController;
|
|
||||||
import com.android.settings.development.bluetooth.BluetoothCodecListPreferenceController;
|
import com.android.settings.development.bluetooth.BluetoothCodecListPreferenceController;
|
||||||
import com.android.settings.development.bluetooth.BluetoothHDAudioPreferenceController;
|
import com.android.settings.development.bluetooth.BluetoothHDAudioPreferenceController;
|
||||||
import com.android.settings.development.bluetooth.BluetoothQualityDialogPreferenceController;
|
import com.android.settings.development.bluetooth.BluetoothQualityDialogPreferenceController;
|
||||||
@@ -813,8 +812,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
|||||||
controllers.add(new AutofillCategoryController(context, lifecycle));
|
controllers.add(new AutofillCategoryController(context, lifecycle));
|
||||||
controllers.add(new AutofillLoggingLevelPreferenceController(context, lifecycle));
|
controllers.add(new AutofillLoggingLevelPreferenceController(context, lifecycle));
|
||||||
controllers.add(new AutofillResetOptionsPreferenceController(context));
|
controllers.add(new AutofillResetOptionsPreferenceController(context));
|
||||||
controllers.add(new BluetoothCodecDialogPreferenceController(context, lifecycle,
|
|
||||||
bluetoothA2dpConfigStore, fragment));
|
|
||||||
controllers.add(
|
controllers.add(
|
||||||
new BluetoothCodecListPreferenceController(
|
new BluetoothCodecListPreferenceController(
|
||||||
context, lifecycle, bluetoothA2dpConfigStore, fragment));
|
context, lifecycle, bluetoothA2dpConfigStore, fragment));
|
||||||
@@ -849,8 +846,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
|||||||
@Override
|
@Override
|
||||||
public void onBluetoothCodecChanged() {
|
public void onBluetoothCodecChanged() {
|
||||||
for (AbstractPreferenceController controller : mPreferenceControllers) {
|
for (AbstractPreferenceController controller : mPreferenceControllers) {
|
||||||
if (controller instanceof AbstractBluetoothDialogPreferenceController
|
if (controller instanceof AbstractBluetoothDialogPreferenceController) {
|
||||||
&& !(controller instanceof BluetoothCodecDialogPreferenceController)) {
|
|
||||||
((AbstractBluetoothDialogPreferenceController) controller)
|
((AbstractBluetoothDialogPreferenceController) controller)
|
||||||
.onBluetoothCodecUpdated();
|
.onBluetoothCodecUpdated();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public abstract class AbstractBluetoothDialogPreferenceController extends
|
|||||||
if (config == null) {
|
if (config == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mBluetoothA2dpConfigStore.setCodecType(config.getCodecType());
|
mBluetoothA2dpConfigStore.setCodecType(config.getExtendedCodecType());
|
||||||
mBluetoothA2dpConfigStore.setSampleRate(config.getSampleRate());
|
mBluetoothA2dpConfigStore.setSampleRate(config.getSampleRate());
|
||||||
mBluetoothA2dpConfigStore.setBitsPerSample(config.getBitsPerSample());
|
mBluetoothA2dpConfigStore.setBitsPerSample(config.getBitsPerSample());
|
||||||
mBluetoothA2dpConfigStore.setChannelMode(config.getChannelMode());
|
mBluetoothA2dpConfigStore.setChannelMode(config.getChannelMode());
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.development.bluetooth;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.RadioGroup;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog preference to set the Bluetooth A2DP config of codec
|
|
||||||
*/
|
|
||||||
public class BluetoothCodecDialogPreference extends BaseBluetoothDialogPreference implements
|
|
||||||
RadioGroup.OnCheckedChangeListener {
|
|
||||||
|
|
||||||
public BluetoothCodecDialogPreference(Context context) {
|
|
||||||
super(context);
|
|
||||||
initialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BluetoothCodecDialogPreference(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
initialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BluetoothCodecDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
initialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BluetoothCodecDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
|
|
||||||
int defStyleRes) {
|
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
|
||||||
initialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getRadioButtonGroupId() {
|
|
||||||
return R.id.bluetooth_audio_codec_radio_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initialize(Context context) {
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_default);
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_sbc);
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_aac);
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_aptx);
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_aptx_hd);
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_ldac);
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_lc3);
|
|
||||||
mRadioButtonIds.add(R.id.bluetooth_audio_codec_opus);
|
|
||||||
String[] stringArray = context.getResources().getStringArray(
|
|
||||||
com.android.settingslib.R.array.bluetooth_a2dp_codec_titles);
|
|
||||||
for (int i = 0; i < stringArray.length; i++) {
|
|
||||||
mRadioButtonStrings.add(stringArray[i]);
|
|
||||||
}
|
|
||||||
stringArray = context.getResources()
|
|
||||||
.getStringArray(com.android.settingslib.R.array.bluetooth_a2dp_codec_summaries);
|
|
||||||
for (int i = 0; i < stringArray.length; i++) {
|
|
||||||
mSummaryStrings.add(stringArray[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.development.bluetooth;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothA2dp;
|
|
||||||
import android.bluetooth.BluetoothCodecConfig;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settings.development.BluetoothA2dpConfigStore;
|
|
||||||
import com.android.settings.development.Flags;
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog preference controller to set the Bluetooth A2DP config of codec
|
|
||||||
*/
|
|
||||||
public class BluetoothCodecDialogPreferenceController extends
|
|
||||||
AbstractBluetoothDialogPreferenceController {
|
|
||||||
|
|
||||||
private static final String KEY = "bluetooth_audio_codec_settings";
|
|
||||||
private static final String TAG = "BtCodecCtr";
|
|
||||||
|
|
||||||
@Nullable private final Callback mCallback;
|
|
||||||
|
|
||||||
public BluetoothCodecDialogPreferenceController(Context context, Lifecycle lifecycle,
|
|
||||||
BluetoothA2dpConfigStore store,
|
|
||||||
@Nullable Callback callback) {
|
|
||||||
super(context, lifecycle, store);
|
|
||||||
mCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAvailable() {
|
|
||||||
return !Flags.a2dpOffloadCodecExtensibilitySettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPreferenceKey() {
|
|
||||||
return KEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void displayPreference(PreferenceScreen screen) {
|
|
||||||
super.displayPreference(screen);
|
|
||||||
((BaseBluetoothDialogPreference) mPreference).setCallback(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Integer> getSelectableIndex() {
|
|
||||||
List<Integer> index = new ArrayList<>();
|
|
||||||
final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp;
|
|
||||||
|
|
||||||
index.add(getDefaultIndex());
|
|
||||||
if (bluetoothA2dp == null) {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
final BluetoothDevice activeDevice = getA2dpActiveDevice();
|
|
||||||
if (activeDevice == null) {
|
|
||||||
Log.d(TAG, "Unable to get selectable index. No Active Bluetooth device");
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
// Check HD audio is enabled, display the available list.
|
|
||||||
if (bluetoothA2dp.isOptionalCodecsEnabled(activeDevice)
|
|
||||||
== BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
|
|
||||||
List<BluetoothCodecConfig> configs = getSelectableConfigs(activeDevice);
|
|
||||||
if (configs != null) {
|
|
||||||
return getIndexFromConfig(configs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If HD audio is disabled, SBC is the only one available codec.
|
|
||||||
index.add(convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC));
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeConfigurationValues(final int index) {
|
|
||||||
int codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC; // default
|
|
||||||
int codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
final BluetoothDevice activeDevice = getA2dpActiveDevice();
|
|
||||||
codecTypeValue = getHighestCodec(mBluetoothA2dp, activeDevice,
|
|
||||||
getSelectableConfigs(activeDevice));
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3;
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS;
|
|
||||||
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mBluetoothA2dpConfigStore.setCodecType(codecTypeValue);
|
|
||||||
mBluetoothA2dpConfigStore.setCodecPriority(codecPriorityValue);
|
|
||||||
|
|
||||||
// Once user changes codec, to reset configs with highest quality.
|
|
||||||
final BluetoothCodecConfig config = getSelectableByCodecType(codecTypeValue);
|
|
||||||
if (config == null) {
|
|
||||||
Log.d(TAG, "Selectable config is null. Unable to reset");
|
|
||||||
}
|
|
||||||
mBluetoothA2dpConfigStore.setSampleRate(getHighestSampleRate(config));
|
|
||||||
mBluetoothA2dpConfigStore.setBitsPerSample(getHighestBitsPerSample(config));
|
|
||||||
mBluetoothA2dpConfigStore.setChannelMode(getHighestChannelMode(config));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getCurrentIndexByConfig(BluetoothCodecConfig config) {
|
|
||||||
if (config == null) {
|
|
||||||
Log.e(TAG, "Unable to get current config index. Config is null.");
|
|
||||||
}
|
|
||||||
return convertCfgToBtnIndex(config.getCodecType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onIndexUpdated(int index) {
|
|
||||||
super.onIndexUpdated(index);
|
|
||||||
mCallback.onBluetoothCodecChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onHDAudioEnabled(boolean enabled) {
|
|
||||||
writeConfigurationValues(/* index= */ 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Integer> getIndexFromConfig(List<BluetoothCodecConfig> configs) {
|
|
||||||
List<Integer> indexArray = new ArrayList<>();
|
|
||||||
for (BluetoothCodecConfig config : configs) {
|
|
||||||
indexArray.add(convertCfgToBtnIndex(config.getCodecType()));
|
|
||||||
}
|
|
||||||
return indexArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
int convertCfgToBtnIndex(int config) {
|
|
||||||
int index = getDefaultIndex();
|
|
||||||
switch (config) {
|
|
||||||
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
|
|
||||||
index = 1;
|
|
||||||
break;
|
|
||||||
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
|
|
||||||
index = 2;
|
|
||||||
break;
|
|
||||||
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
|
|
||||||
index = 3;
|
|
||||||
break;
|
|
||||||
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
|
|
||||||
index = 4;
|
|
||||||
break;
|
|
||||||
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
|
|
||||||
index = 5;
|
|
||||||
break;
|
|
||||||
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
|
|
||||||
index = 7;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Log.e(TAG, "Unsupported config:" + config);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,7 +32,6 @@ import androidx.preference.PreferenceScreen;
|
|||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.settings.development.BluetoothA2dpConfigStore;
|
import com.android.settings.development.BluetoothA2dpConfigStore;
|
||||||
import com.android.settings.development.Flags;
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -62,9 +61,7 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
boolean available = Flags.a2dpOffloadCodecExtensibilitySettings();
|
return true;
|
||||||
Log.d(TAG, "isAvailable: " + available);
|
|
||||||
return available;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,10 +77,6 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(@Nullable Preference preference, @NonNull Object newValue) {
|
public boolean onPreferenceChange(@Nullable Preference preference, @NonNull Object newValue) {
|
||||||
if (!Flags.a2dpOffloadCodecExtensibilitySettings()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mListPreference == null) {
|
if (mListPreference == null) {
|
||||||
Log.e(TAG, "onPreferenceChange: List preference is null");
|
Log.e(TAG, "onPreferenceChange: List preference is null");
|
||||||
return false;
|
return false;
|
||||||
@@ -115,7 +108,7 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre
|
|||||||
}
|
}
|
||||||
|
|
||||||
BluetoothCodecConfig codecConfig =
|
BluetoothCodecConfig codecConfig =
|
||||||
mBluetoothA2dpConfigStore.createCodecConfigFromCodecType();
|
mBluetoothA2dpConfigStore.createCodecConfig();
|
||||||
Log.d(TAG, "onPreferenceChange: setCodecConfigPreference: " + codecConfig.toString());
|
Log.d(TAG, "onPreferenceChange: setCodecConfigPreference: " + codecConfig.toString());
|
||||||
bluetoothA2dp.setCodecConfigPreference(activeDevice, codecConfig);
|
bluetoothA2dp.setCodecConfigPreference(activeDevice, codecConfig);
|
||||||
if (mCallback != null) {
|
if (mCallback != null) {
|
||||||
@@ -128,9 +121,6 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre
|
|||||||
@Override
|
@Override
|
||||||
public void updateState(@Nullable Preference preference) {
|
public void updateState(@Nullable Preference preference) {
|
||||||
super.updateState(preference);
|
super.updateState(preference);
|
||||||
if (!Flags.a2dpOffloadCodecExtensibilitySettings()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isHDAudioEnabled()) {
|
if (!isHDAudioEnabled()) {
|
||||||
Log.d(TAG, "updateState: HD Audio is disabled");
|
Log.d(TAG, "updateState: HD Audio is disabled");
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
|
|||||||
if (mSystemPreference != null) {
|
if (mSystemPreference != null) {
|
||||||
mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate);
|
mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate);
|
||||||
mSystemPreference.setTitle(mContext.getString(R.string.storage_os_name,
|
mSystemPreference.setTitle(mContext.getString(R.string.storage_os_name,
|
||||||
Build.VERSION.RELEASE));
|
Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY));
|
||||||
}
|
}
|
||||||
if (mTemporaryFilesPreference != null) {
|
if (mTemporaryFilesPreference != null) {
|
||||||
mTemporaryFilesPreference.setStorageSize(storageCache.temporaryFilesSize, mTotalSize,
|
mTemporaryFilesPreference.setStorageSize(storageCache.temporaryFilesSize, mTotalSize,
|
||||||
|
|||||||
@@ -29,8 +29,7 @@ import com.android.settingslib.datastore.KeyValueStore
|
|||||||
import com.android.settingslib.datastore.KeyedObservableDelegate
|
import com.android.settingslib.datastore.KeyedObservableDelegate
|
||||||
import com.android.settingslib.datastore.SettingsStore
|
import com.android.settingslib.datastore.SettingsStore
|
||||||
import com.android.settingslib.datastore.SettingsSystemStore
|
import com.android.settingslib.datastore.SettingsSystemStore
|
||||||
import com.android.settingslib.metadata.BooleanValue
|
import com.android.settingslib.metadata.BooleanPreference
|
||||||
import com.android.settingslib.metadata.PersistentPreference
|
|
||||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||||
import com.android.settingslib.metadata.PreferenceMetadata
|
import com.android.settingslib.metadata.PreferenceMetadata
|
||||||
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
||||||
@@ -46,8 +45,7 @@ class AutoBrightnessScreen :
|
|||||||
PreferenceScreenBinding,
|
PreferenceScreenBinding,
|
||||||
PreferenceAvailabilityProvider,
|
PreferenceAvailabilityProvider,
|
||||||
PreferenceRestrictionMixin,
|
PreferenceRestrictionMixin,
|
||||||
PersistentPreference<Boolean>,
|
BooleanPreference {
|
||||||
BooleanValue {
|
|
||||||
override val key: String
|
override val key: String
|
||||||
get() = KEY
|
get() = KEY
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ import com.android.settings.flags.Flags
|
|||||||
import com.android.settingslib.PrimarySwitchPreference
|
import com.android.settingslib.PrimarySwitchPreference
|
||||||
import com.android.settingslib.datastore.KeyValueStore
|
import com.android.settingslib.datastore.KeyValueStore
|
||||||
import com.android.settingslib.datastore.Permissions
|
import com.android.settingslib.datastore.Permissions
|
||||||
import com.android.settingslib.metadata.BooleanValue
|
import com.android.settingslib.metadata.BooleanPreference
|
||||||
import com.android.settingslib.metadata.PersistentPreference
|
|
||||||
import com.android.settingslib.metadata.PreferenceMetadata
|
import com.android.settingslib.metadata.PreferenceMetadata
|
||||||
import com.android.settingslib.metadata.PreferenceSummaryProvider
|
import com.android.settingslib.metadata.PreferenceSummaryProvider
|
||||||
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
||||||
@@ -41,8 +40,7 @@ import com.android.settingslib.preference.PreferenceScreenCreator
|
|||||||
class DarkModeScreen(context: Context) :
|
class DarkModeScreen(context: Context) :
|
||||||
PreferenceScreenCreator,
|
PreferenceScreenCreator,
|
||||||
PreferenceScreenBinding,
|
PreferenceScreenBinding,
|
||||||
PersistentPreference<Boolean>,
|
BooleanPreference,
|
||||||
BooleanValue,
|
|
||||||
PreferenceSummaryProvider {
|
PreferenceSummaryProvider {
|
||||||
|
|
||||||
private val darkModeStorage = DarkModeStorage(context)
|
private val darkModeStorage = DarkModeStorage(context)
|
||||||
|
|||||||
@@ -257,16 +257,10 @@ public class OneHandedSettingsUtils {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
|
||||||
// Checks QS_SHORTCUT_KEY
|
// Checks QS_SHORTCUT_KEY
|
||||||
final String targetsQs = Settings.Secure.getStringForUser(context.getContentResolver(),
|
final String targetsQs = Settings.Secure.getStringForUser(context.getContentResolver(),
|
||||||
Settings.Secure.ACCESSIBILITY_QS_TARGETS, sCurrentUserId);
|
Settings.Secure.ACCESSIBILITY_QS_TARGETS, sCurrentUserId);
|
||||||
if (!TextUtils.isEmpty(targetsQs) && targetsQs.contains(ONE_HANDED_MODE_TARGET_NAME)) {
|
return !TextUtils.isEmpty(targetsQs) && targetsQs.contains(ONE_HANDED_MODE_TARGET_NAME);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,11 +18,16 @@ package com.android.settings.regionalpreferences;
|
|||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -36,6 +41,19 @@ public class FirstDayOfWeekItemFragment extends DashboardFragment {
|
|||||||
private static final String KEY_PREFERENCE_CATEGORY_FIRST_DAY_OF_WEEK_ITEM =
|
private static final String KEY_PREFERENCE_CATEGORY_FIRST_DAY_OF_WEEK_ITEM =
|
||||||
"first_day_of_week_item_category";
|
"first_day_of_week_item_category";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
|
||||||
|
MetricsFeatureProvider metricsFeatureProvider =
|
||||||
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||||
|
String action = getIntent() != null ? getIntent().getAction() : "";
|
||||||
|
if (Settings.ACTION_FIRST_DAY_OF_WEEK_SETTINGS.equals(action)) {
|
||||||
|
metricsFeatureProvider.action(
|
||||||
|
context, SettingsEnums.ACTION_OPEN_FIRST_DAY_OF_WEEK_OUTSIDE_SETTINGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getPreferenceScreenResId() {
|
protected int getPreferenceScreenResId() {
|
||||||
return R.xml.regional_preferences_first_day_of_week;
|
return R.xml.regional_preferences_first_day_of_week;
|
||||||
|
|||||||
@@ -18,12 +18,17 @@ package com.android.settings.regionalpreferences;
|
|||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.flags.Flags;
|
import com.android.settings.flags.Flags;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -36,6 +41,20 @@ public class MeasurementSystemItemFragment extends DashboardFragment {
|
|||||||
private static final String LOG_TAG = "MeasurementSystemItemFragment";
|
private static final String LOG_TAG = "MeasurementSystemItemFragment";
|
||||||
private static final String KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM =
|
private static final String KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM =
|
||||||
"measurement_system_item_category";
|
"measurement_system_item_category";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
|
||||||
|
MetricsFeatureProvider metricsFeatureProvider =
|
||||||
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||||
|
String action = getIntent() != null ? getIntent().getAction() : "";
|
||||||
|
if (Settings.ACTION_MEASUREMENT_SYSTEM_SETTINGS.equals(action)) {
|
||||||
|
metricsFeatureProvider.action(
|
||||||
|
context, SettingsEnums.ACTION_OPEN_MEASUREMENT_SYSTEM_OUTSIDE_SETTINGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getPreferenceScreenResId() {
|
protected int getPreferenceScreenResId() {
|
||||||
return R.xml.regional_preferences_measurement_system;
|
return R.xml.regional_preferences_measurement_system;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.settings.regionalpreferences;
|
package com.android.settings.regionalpreferences;
|
||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -35,6 +36,8 @@ import com.android.internal.app.LocalePicker;
|
|||||||
import com.android.internal.app.LocaleStore;
|
import com.android.internal.app.LocaleStore;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -61,7 +64,7 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return 0;
|
return SettingsEnums.CHANGE_REGION_DIALOG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -110,6 +113,7 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final int mDialogType;
|
private final int mDialogType;
|
||||||
private final LocaleStore.LocaleInfo mLocaleInfo;
|
private final LocaleStore.LocaleInfo mLocaleInfo;
|
||||||
|
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
|
|
||||||
RegionDialogController(
|
RegionDialogController(
|
||||||
@NonNull Context context, @NonNull RegionDialogFragment dialogFragment) {
|
@NonNull Context context, @NonNull RegionDialogFragment dialogFragment) {
|
||||||
@@ -117,6 +121,8 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
|
|||||||
Bundle arguments = dialogFragment.getArguments();
|
Bundle arguments = dialogFragment.getArguments();
|
||||||
mDialogType = arguments.getInt(ARG_DIALOG_TYPE);
|
mDialogType = arguments.getInt(ARG_DIALOG_TYPE);
|
||||||
mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(ARG_TARGET_LOCALE);
|
mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(ARG_TARGET_LOCALE);
|
||||||
|
mMetricsFeatureProvider =
|
||||||
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -124,6 +130,14 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
|
|||||||
if (mDialogType == DIALOG_CHANGE_LOCALE_REGION) {
|
if (mDialogType == DIALOG_CHANGE_LOCALE_REGION) {
|
||||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||||
updateRegion(mLocaleInfo.getLocale().toLanguageTag());
|
updateRegion(mLocaleInfo.getLocale().toLanguageTag());
|
||||||
|
mMetricsFeatureProvider.action(
|
||||||
|
mContext,
|
||||||
|
SettingsEnums.ACTION_CHANGE_REGION_DIALOG_POSITIVE_BTN_CLICKED);
|
||||||
|
}
|
||||||
|
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||||
|
mMetricsFeatureProvider.action(
|
||||||
|
mContext,
|
||||||
|
SettingsEnums.ACTION_CHANGE_REGION_DIALOG_NEGATIVE_BTN_CLICKED);
|
||||||
}
|
}
|
||||||
dismiss();
|
dismiss();
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package com.android.settings.regionalpreferences;
|
package com.android.settings.regionalpreferences;
|
||||||
|
|
||||||
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
@@ -25,8 +27,10 @@ import com.android.internal.app.LocaleStore;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.flags.Flags;
|
import com.android.settings.flags.Flags;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,6 +48,19 @@ public class RegionPickerFragment extends DashboardFragment{
|
|||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
|
||||||
|
MetricsFeatureProvider metricsFeatureProvider =
|
||||||
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||||
|
String action = getIntent() != null ? getIntent().getAction() : "";
|
||||||
|
if (Settings.ACTION_REGION_SETTINGS.equals(action)) {
|
||||||
|
metricsFeatureProvider.action(
|
||||||
|
context, SettingsEnums.ACTION_OPEN_REGION_OUTSIDE_SETTINGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getPreferenceScreenResId() {
|
protected int getPreferenceScreenResId() {
|
||||||
return R.xml.system_region_picker;
|
return R.xml.system_region_picker;
|
||||||
@@ -56,7 +73,7 @@ public class RegionPickerFragment extends DashboardFragment{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return 0;
|
return SettingsEnums.REGION_SETTINGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,11 +18,16 @@ package com.android.settings.regionalpreferences;
|
|||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -36,6 +41,19 @@ public class TemperatureUnitFragment extends DashboardFragment {
|
|||||||
private static final String KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT =
|
private static final String KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT =
|
||||||
"temperature_unit_category";
|
"temperature_unit_category";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
|
||||||
|
MetricsFeatureProvider metricsFeatureProvider =
|
||||||
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||||
|
String action = getIntent() != null ? getIntent().getAction() : "";
|
||||||
|
if (Settings.ACTION_TEMPERATURE_UNIT_SETTINGS.equals(action)) {
|
||||||
|
metricsFeatureProvider.action(
|
||||||
|
context, SettingsEnums.ACTION_OPEN_TEMPERATURE_UNIT_OUTSIDE_SETTINGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getPreferenceScreenResId() {
|
protected int getPreferenceScreenResId() {
|
||||||
return R.xml.regional_preferences_temperature;
|
return R.xml.regional_preferences_temperature;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -67,6 +68,7 @@ import com.android.settingslib.bluetooth.BluetoothEventManager;
|
|||||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||||
|
import com.android.settingslib.bluetooth.LeAudioProfile;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
@@ -77,7 +79,6 @@ import com.android.settingslib.flags.Flags;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -89,8 +90,10 @@ import org.mockito.Spy;
|
|||||||
import org.mockito.junit.MockitoJUnit;
|
import org.mockito.junit.MockitoJUnit;
|
||||||
import org.mockito.junit.MockitoRule;
|
import org.mockito.junit.MockitoRule;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.Shadows;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadow.api.Shadow;
|
import org.robolectric.shadow.api.Shadow;
|
||||||
|
import org.robolectric.shadows.ShadowListView;
|
||||||
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -483,19 +486,46 @@ public class AudioSharingCallAudioPreferenceControllerTest {
|
|||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog.isShowing()).isTrue();
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
assertThat(dialog.getListView().getCount()).isEqualTo(2);
|
assertThat(dialog.getListView().getCount()).isEqualTo(2);
|
||||||
ArrayList<View> outViews = new ArrayList<>();
|
ShadowListView listView = Shadows.shadowOf(dialog.getListView());
|
||||||
dialog.getListView()
|
View view1 = listView.findItemContainingText(TEST_DEVICE_NAME1);
|
||||||
.findViewsWithText(outViews, TEST_DEVICE_NAME1, View.FIND_VIEWS_WITH_TEXT);
|
assertThat(view1).isNotNull();
|
||||||
assertThat(outViews.size()).isEqualTo(1);
|
assertThat(view1 instanceof CheckedTextView).isTrue();
|
||||||
View view = Iterables.getOnlyElement(outViews);
|
assertThat(((CheckedTextView) view1).isChecked()).isTrue();
|
||||||
assertThat(view instanceof CheckedTextView).isTrue();
|
View view2 = listView.findItemContainingText(TEST_DEVICE_NAME2);
|
||||||
assertThat(((CheckedTextView) view).isChecked()).isTrue();
|
assertThat(view2).isNotNull();
|
||||||
|
assertThat(view2 instanceof CheckedTextView).isTrue();
|
||||||
|
assertThat(((CheckedTextView) view2).isChecked()).isFalse();
|
||||||
|
|
||||||
verify(mFeatureFactory.metricsFeatureProvider)
|
verify(mFeatureFactory.metricsFeatureProvider)
|
||||||
.visible(
|
.visible(
|
||||||
/* context= */ eq(null),
|
/* context= */ eq(null),
|
||||||
/* source= */ anyInt(),
|
/* source= */ anyInt(),
|
||||||
eq(SettingsEnums.DIALOG_AUDIO_SHARING_CALL_AUDIO),
|
eq(SettingsEnums.DIALOG_AUDIO_SHARING_CALL_AUDIO),
|
||||||
/* latency= */ anyInt());
|
/* latency= */ anyInt());
|
||||||
|
|
||||||
|
LeAudioProfile leAudioProfile = mock(LeAudioProfile.class);
|
||||||
|
when(mBtProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile);
|
||||||
|
|
||||||
|
// Perform click to switch call audio device by set active
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
|
||||||
|
int index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME2);
|
||||||
|
listView.performItemClick(index);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(((CheckedTextView) view1).isChecked()).isFalse();
|
||||||
|
assertThat(((CheckedTextView) view2).isChecked()).isTrue();
|
||||||
|
verify(mCachedDevice3).setActive();
|
||||||
|
verify(leAudioProfile, never()).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID2);
|
||||||
|
|
||||||
|
// Perform click to switch call audio device with API
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
|
||||||
|
Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID2);
|
||||||
|
index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME1);
|
||||||
|
listView.performItemClick(index);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(((CheckedTextView) view1).isChecked()).isTrue();
|
||||||
|
assertThat(((CheckedTextView) view2).isChecked()).isFalse();
|
||||||
|
verify(mCachedDevice1, never()).setActive();
|
||||||
|
verify(leAudioProfile).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -584,6 +584,7 @@ public class AudioSharingDevicePreferenceControllerTest {
|
|||||||
public void testInCallState_showCallStateTitleAndSetActiveOnDeviceClick() {
|
public void testInCallState_showCallStateTitleAndSetActiveOnDeviceClick() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
|
||||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||||
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
||||||
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||||
@@ -609,6 +610,7 @@ public class AudioSharingDevicePreferenceControllerTest {
|
|||||||
public void testInCallState_enableHysteresisFix_setAndSaveActiveOnDeviceClick() {
|
public void testInCallState_enableHysteresisFix_setAndSaveActiveOnDeviceClick() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
|
||||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||||
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
||||||
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ public class AudioSharingDialogHandlerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void handleUserTriggeredDeviceConnected_inCall_setActive() {
|
public void handleUserTriggeredDeviceConnected_inCall_setActive() {
|
||||||
mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
|
||||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||||
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
||||||
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||||
@@ -218,6 +219,7 @@ public class AudioSharingDialogHandlerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void handleUserTriggeredDeviceConnected_inCall_enableHysteresisFix_setAndSaveActive() {
|
public void handleUserTriggeredDeviceConnected_inCall_enableHysteresisFix_setAndSaveActive() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
|
||||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||||
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
|
||||||
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||||
@@ -452,6 +454,7 @@ public class AudioSharingDialogHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleDeviceConnected_inCall_doNothing() {
|
public void handleDeviceConnected_inCall_doNothing() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
|
||||||
when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL);
|
when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL);
|
||||||
setUpBroadcast(true);
|
setUpBroadcast(true);
|
||||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
|
||||||
|
|||||||
@@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.development;
|
|
||||||
|
|
||||||
import static com.android.settings.development.AbstractBluetoothA2dpPreferenceController
|
|
||||||
.STREAMING_LABEL_ID;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.doNothing;
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothA2dp;
|
|
||||||
import android.bluetooth.BluetoothCodecConfig;
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.preference.ListPreference;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
public class AbstractBluetoothA2dpPreferenceControllerTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private BluetoothA2dp mBluetoothA2dp;
|
|
||||||
@Mock
|
|
||||||
private BluetoothCodecConfig mBluetoothCodecConfig;
|
|
||||||
@Mock
|
|
||||||
private ListPreference mPreference;
|
|
||||||
@Mock
|
|
||||||
private PreferenceScreen mScreen;
|
|
||||||
@Mock
|
|
||||||
private BluetoothA2dpConfigStore mBluetoothA2dpConfigStore;
|
|
||||||
|
|
||||||
private LifecycleOwner mLifecycleOwner;
|
|
||||||
private Lifecycle mLifecycle;
|
|
||||||
private Context mContext;
|
|
||||||
private AbstractBluetoothA2dpPreferenceController mController;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = RuntimeEnvironment.application;
|
|
||||||
mLifecycleOwner = () -> mLifecycle;
|
|
||||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
|
||||||
mController = spy(new AbstractBluetoothA2dpPreferenceControllerImpl(mContext, mLifecycle,
|
|
||||||
mBluetoothA2dpConfigStore));
|
|
||||||
mController.mBluetoothAdapter = null;
|
|
||||||
doReturn(mBluetoothCodecConfig).when(mController).getCodecConfig(null);
|
|
||||||
doNothing().when(mController).setCodecConfigPreference(any(), any());
|
|
||||||
when(mBluetoothA2dpConfigStore.createCodecConfig()).thenReturn(mBluetoothCodecConfig);
|
|
||||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Ignore
|
|
||||||
public void onPreferenceChange_bluetoothConnected_shouldUpdateCodec() {
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
|
|
||||||
mController.onPreferenceChange(mPreference, "" /* new value */);
|
|
||||||
|
|
||||||
verify(mController).setCodecConfigPreference(any(), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPreferenceChange_bluetoothNotConnected_shouldNotUpdateCodec() {
|
|
||||||
mController.onBluetoothServiceDisconnected();
|
|
||||||
|
|
||||||
mController.onPreferenceChange(mPreference, "" /* new value */);
|
|
||||||
|
|
||||||
verify(mController, never()).setCodecConfigPreference(any(), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Ignore
|
|
||||||
public void updateState_option2Set_shouldUpdateToOption2() {
|
|
||||||
when(mBluetoothCodecConfig.getSampleRate()).thenReturn(
|
|
||||||
BluetoothCodecConfig.SAMPLE_RATE_48000);
|
|
||||||
|
|
||||||
doReturn(2).when(mController).getCurrentA2dpSettingIndex(any());
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
verify(mPreference).setValue(mController.getListValues()[2]);
|
|
||||||
verify(mPreference).setSummary(mContext.getString(STREAMING_LABEL_ID,
|
|
||||||
mController.getListSummaries()[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onBluetoothServiceConnected_shouldUpdateState() {
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
|
|
||||||
verify(mController).updateState(mPreference);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class AbstractBluetoothA2dpPreferenceControllerImpl
|
|
||||||
extends AbstractBluetoothA2dpPreferenceController {
|
|
||||||
|
|
||||||
private AbstractBluetoothA2dpPreferenceControllerImpl(Context context,
|
|
||||||
Lifecycle lifecycle, BluetoothA2dpConfigStore store) {
|
|
||||||
super(context, lifecycle, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPreferenceKey() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String[] getListValues() {
|
|
||||||
return new String[]{"1", "2", "3"};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String[] getListSummaries() {
|
|
||||||
return new String[]{"foo", "bar", "foobar"};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeConfigurationValues(Object newValue) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getCurrentA2dpSettingIndex(BluetoothCodecConfig config) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getDefaultIndex() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -220,7 +220,7 @@ public class AbstractBluetoothDialogPreferenceControllerTest {
|
|||||||
mActiveDevice)).thenReturn(mCodecStatus);
|
mActiveDevice)).thenReturn(mCodecStatus);
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
||||||
|
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getCodecType());
|
verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getExtendedCodecType());
|
||||||
verify(mBluetoothA2dpConfigStore).setSampleRate(mCodecConfigAAC.getSampleRate());
|
verify(mBluetoothA2dpConfigStore).setSampleRate(mCodecConfigAAC.getSampleRate());
|
||||||
verify(mBluetoothA2dpConfigStore).setBitsPerSample(mCodecConfigAAC.getBitsPerSample());
|
verify(mBluetoothA2dpConfigStore).setBitsPerSample(mCodecConfigAAC.getBitsPerSample());
|
||||||
verify(mBluetoothA2dpConfigStore).setChannelMode(mCodecConfigAAC.getChannelMode());
|
verify(mBluetoothA2dpConfigStore).setChannelMode(mCodecConfigAAC.getChannelMode());
|
||||||
|
|||||||
@@ -1,279 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.development.bluetooth;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
|
||||||
import static org.mockito.Mockito.eq;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothA2dp;
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
|
||||||
import android.bluetooth.BluetoothCodecConfig;
|
|
||||||
import android.bluetooth.BluetoothCodecStatus;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.bluetooth.BluetoothProfile;
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settings.development.BluetoothA2dpConfigStore;
|
|
||||||
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.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
public class BluetoothCodecDialogPreferenceControllerTest {
|
|
||||||
|
|
||||||
private static final String DEVICE_ADDRESS = "00:11:22:33:44:55";
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private BluetoothA2dp mBluetoothA2dp;
|
|
||||||
@Mock
|
|
||||||
private BluetoothAdapter mBluetoothAdapter;
|
|
||||||
@Mock
|
|
||||||
private PreferenceScreen mScreen;
|
|
||||||
@Mock
|
|
||||||
private AbstractBluetoothPreferenceController.Callback mCallback;
|
|
||||||
|
|
||||||
private BluetoothCodecDialogPreferenceController mController;
|
|
||||||
private BluetoothCodecDialogPreference mPreference;
|
|
||||||
private BluetoothA2dpConfigStore mBluetoothA2dpConfigStore;
|
|
||||||
private BluetoothCodecStatus mCodecStatus;
|
|
||||||
private BluetoothCodecConfig mCodecConfigAAC;
|
|
||||||
private BluetoothCodecConfig mCodecConfigSBC;
|
|
||||||
private BluetoothCodecConfig mCodecConfigAPTX;
|
|
||||||
private BluetoothCodecConfig mCodecConfigAPTXHD;
|
|
||||||
private BluetoothCodecConfig mCodecConfigLDAC;
|
|
||||||
private BluetoothCodecConfig mCodecConfigOPUS;
|
|
||||||
private BluetoothDevice mActiveDevice;
|
|
||||||
private Context mContext;
|
|
||||||
private LifecycleOwner mLifecycleOwner;
|
|
||||||
private Lifecycle mLifecycle;
|
|
||||||
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = RuntimeEnvironment.application;
|
|
||||||
mLifecycleOwner = () -> mLifecycle;
|
|
||||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
|
||||||
mBluetoothA2dpConfigStore = spy(new BluetoothA2dpConfigStore());
|
|
||||||
mActiveDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(DEVICE_ADDRESS);
|
|
||||||
mController = new BluetoothCodecDialogPreferenceController(mContext, mLifecycle,
|
|
||||||
mBluetoothA2dpConfigStore, mCallback);
|
|
||||||
mController.mBluetoothAdapter = mBluetoothAdapter;
|
|
||||||
mPreference = new BluetoothCodecDialogPreference(mContext);
|
|
||||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
mCodecConfigSBC = new BluetoothCodecConfig.Builder()
|
|
||||||
.setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
|
|
||||||
.setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)
|
|
||||||
.setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_96000
|
|
||||||
| BluetoothCodecConfig.SAMPLE_RATE_176400)
|
|
||||||
.setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_32)
|
|
||||||
.setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_MONO
|
|
||||||
| BluetoothCodecConfig.CHANNEL_MODE_STEREO)
|
|
||||||
.build();
|
|
||||||
mCodecConfigAAC = new BluetoothCodecConfig.Builder()
|
|
||||||
.setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
|
|
||||||
.setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)
|
|
||||||
.setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000
|
|
||||||
| BluetoothCodecConfig.SAMPLE_RATE_88200)
|
|
||||||
.setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16
|
|
||||||
| BluetoothCodecConfig.BITS_PER_SAMPLE_24)
|
|
||||||
.setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO)
|
|
||||||
.build();
|
|
||||||
mCodecConfigAPTX = new BluetoothCodecConfig.Builder()
|
|
||||||
.setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX)
|
|
||||||
.build();
|
|
||||||
mCodecConfigAPTXHD = new BluetoothCodecConfig.Builder()
|
|
||||||
.setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD)
|
|
||||||
.build();
|
|
||||||
mCodecConfigLDAC = new BluetoothCodecConfig.Builder()
|
|
||||||
.setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
|
|
||||||
.build();
|
|
||||||
mCodecConfigOPUS = new BluetoothCodecConfig.Builder()
|
|
||||||
.setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
|
|
||||||
.build();
|
|
||||||
when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.A2DP)))
|
|
||||||
.thenReturn(Arrays.asList(mActiveDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeConfigurationValues_selectDefault_setHighest() {
|
|
||||||
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC,
|
|
||||||
mCodecConfigSBC};
|
|
||||||
mCodecStatus = new BluetoothCodecStatus.Builder()
|
|
||||||
.setCodecConfig(mCodecConfigSBC)
|
|
||||||
.setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs))
|
|
||||||
.build();
|
|
||||||
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
|
||||||
when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
|
|
||||||
BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
|
|
||||||
mController.writeConfigurationValues(0);
|
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(
|
|
||||||
BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeConfigurationValues_checkCodec() {
|
|
||||||
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC,
|
|
||||||
mCodecConfigSBC, mCodecConfigAPTX, mCodecConfigAPTXHD, mCodecConfigLDAC};
|
|
||||||
mCodecStatus = new BluetoothCodecStatus.Builder()
|
|
||||||
.setCodecConfig(mCodecConfigSBC)
|
|
||||||
.setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs))
|
|
||||||
.build();
|
|
||||||
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
|
|
||||||
mController.writeConfigurationValues(1);
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(
|
|
||||||
BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC);
|
|
||||||
|
|
||||||
mController.writeConfigurationValues(2);
|
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC);
|
|
||||||
|
|
||||||
mController.writeConfigurationValues(3);
|
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX);
|
|
||||||
|
|
||||||
mController.writeConfigurationValues(4);
|
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(
|
|
||||||
BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD);
|
|
||||||
|
|
||||||
mController.writeConfigurationValues(5);
|
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC);
|
|
||||||
|
|
||||||
mController.writeConfigurationValues(7);
|
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(
|
|
||||||
BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeConfigurationValues_resetHighestConfig() {
|
|
||||||
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC, mCodecConfigAPTX,
|
|
||||||
mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigOPUS};
|
|
||||||
mCodecStatus = new BluetoothCodecStatus.Builder()
|
|
||||||
.setCodecConfig(mCodecConfigAAC)
|
|
||||||
.setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs))
|
|
||||||
.build();
|
|
||||||
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
mController.writeConfigurationValues(2);
|
|
||||||
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecPriority(
|
|
||||||
BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST);
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setSampleRate(
|
|
||||||
BluetoothCodecConfig.SAMPLE_RATE_88200);
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setBitsPerSample(
|
|
||||||
BluetoothCodecConfig.BITS_PER_SAMPLE_24);
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setChannelMode(
|
|
||||||
BluetoothCodecConfig.CHANNEL_MODE_STEREO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getCurrentIndexByConfig_verifyIndex() {
|
|
||||||
assertThat(mController.getCurrentIndexByConfig(mCodecConfigAAC)).isEqualTo(
|
|
||||||
mController.convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getCurrentIndexByConfig_verifyOpusIndex() {
|
|
||||||
assertThat(mController.getCurrentIndexByConfig(mCodecConfigOPUS)).isEqualTo(
|
|
||||||
mController.convertCfgToBtnIndex(
|
|
||||||
BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onIndexUpdated_notifyPreference() {
|
|
||||||
mController.onIndexUpdated(0);
|
|
||||||
|
|
||||||
verify(mCallback).onBluetoothCodecChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsOpus() {
|
|
||||||
List<BluetoothCodecConfig> mCodecConfigs = Arrays.asList(mCodecConfigOPUS,
|
|
||||||
mCodecConfigAAC, mCodecConfigSBC);
|
|
||||||
mCodecStatus = new BluetoothCodecStatus.Builder()
|
|
||||||
.setCodecConfig(mCodecConfigOPUS)
|
|
||||||
.setCodecsSelectableCapabilities(mCodecConfigs)
|
|
||||||
.build();
|
|
||||||
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
|
||||||
when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
|
|
||||||
BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
|
|
||||||
mController.onHDAudioEnabled(/* enabled= */ true);
|
|
||||||
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(
|
|
||||||
eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsAAC() {
|
|
||||||
List<BluetoothCodecConfig> mCodecConfigs = Arrays.asList(mCodecConfigOPUS,
|
|
||||||
mCodecConfigAAC, mCodecConfigSBC);
|
|
||||||
mCodecStatus = new BluetoothCodecStatus.Builder()
|
|
||||||
.setCodecConfig(mCodecConfigAAC)
|
|
||||||
.setCodecsSelectableCapabilities(mCodecConfigs)
|
|
||||||
.build();
|
|
||||||
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
|
||||||
when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
|
|
||||||
BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
|
|
||||||
mController.onHDAudioEnabled(/* enabled= */ true);
|
|
||||||
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(
|
|
||||||
eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC));
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
public void onHDAudioEnabled_optionalCodecDisabled_setsCodecTypeAsSBC() {
|
|
||||||
List<BluetoothCodecConfig> mCodecConfigs = Arrays.asList(mCodecConfigOPUS,
|
|
||||||
mCodecConfigAAC, mCodecConfigSBC);
|
|
||||||
mCodecStatus = new BluetoothCodecStatus.Builder()
|
|
||||||
.setCodecConfig(mCodecConfigAAC)
|
|
||||||
.setCodecsSelectableCapabilities(mCodecConfigs)
|
|
||||||
.build();
|
|
||||||
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
|
||||||
when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
|
|
||||||
BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
|
|
||||||
mController.onBluetoothServiceConnected(mBluetoothA2dp);
|
|
||||||
|
|
||||||
mController.onHDAudioEnabled(/* enabled= */ false);
|
|
||||||
|
|
||||||
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(
|
|
||||||
eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.development.bluetooth;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
public class BluetoothCodecDialogPreferenceTest {
|
|
||||||
|
|
||||||
private BluetoothCodecDialogPreference mPreference;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = RuntimeEnvironment.application;
|
|
||||||
mPreference = new BluetoothCodecDialogPreference(mContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getRadioButtonGroupId() {
|
|
||||||
assertThat(mPreference.getRadioButtonGroupId())
|
|
||||||
.isEqualTo(R.id.bluetooth_audio_codec_radio_group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ package com.android.settings.development.bluetooth;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
@@ -35,14 +34,12 @@ import android.bluetooth.BluetoothCodecType;
|
|||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.platform.test.annotations.EnableFlags;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settings.development.BluetoothA2dpConfigStore;
|
import com.android.settings.development.BluetoothA2dpConfigStore;
|
||||||
import com.android.settings.development.Flags;
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -73,6 +70,7 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
private BluetoothCodecType mCodecTypeAAC;
|
private BluetoothCodecType mCodecTypeAAC;
|
||||||
private BluetoothCodecType mCodecTypeSBC;
|
private BluetoothCodecType mCodecTypeSBC;
|
||||||
private BluetoothCodecType mCodecTypeAPTX;
|
private BluetoothCodecType mCodecTypeAPTX;
|
||||||
|
private BluetoothCodecType mCodecTypeAPTXHD;
|
||||||
private BluetoothCodecType mCodecTypeLDAC;
|
private BluetoothCodecType mCodecTypeLDAC;
|
||||||
private BluetoothCodecType mCodecTypeOPUS;
|
private BluetoothCodecType mCodecTypeOPUS;
|
||||||
private List<BluetoothCodecType> mCodecTypes;
|
private List<BluetoothCodecType> mCodecTypes;
|
||||||
@@ -114,6 +112,8 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC);
|
BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC);
|
||||||
mCodecTypeAPTX =
|
mCodecTypeAPTX =
|
||||||
BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX);
|
BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX);
|
||||||
|
mCodecTypeAPTXHD =
|
||||||
|
BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD);
|
||||||
mCodecTypeLDAC =
|
mCodecTypeLDAC =
|
||||||
BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC);
|
BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC);
|
||||||
mCodecTypeOPUS =
|
mCodecTypeOPUS =
|
||||||
@@ -125,6 +125,7 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
mCodecTypeSBC,
|
mCodecTypeSBC,
|
||||||
mCodecTypeAAC,
|
mCodecTypeAAC,
|
||||||
mCodecTypeAPTX,
|
mCodecTypeAPTX,
|
||||||
|
mCodecTypeAPTXHD,
|
||||||
mCodecTypeLDAC,
|
mCodecTypeLDAC,
|
||||||
mCodecTypeOPUS));
|
mCodecTypeOPUS));
|
||||||
|
|
||||||
@@ -212,6 +213,11 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
mController.writeConfigurationValues(String.valueOf(mCodecTypeAPTX.getCodecId())));
|
mController.writeConfigurationValues(String.valueOf(mCodecTypeAPTX.getCodecId())));
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTX);
|
verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTX);
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
mController.writeConfigurationValues(String.valueOf(
|
||||||
|
mCodecTypeAPTXHD.getCodecId())));
|
||||||
|
verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTXHD);
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
mController.writeConfigurationValues(String.valueOf(mCodecTypeLDAC.getCodecId())));
|
mController.writeConfigurationValues(String.valueOf(mCodecTypeLDAC.getCodecId())));
|
||||||
verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeLDAC);
|
verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeLDAC);
|
||||||
@@ -244,7 +250,6 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
|
||||||
public void onPreferenceChange_notifyPreference() {
|
public void onPreferenceChange_notifyPreference() {
|
||||||
assertFalse(
|
assertFalse(
|
||||||
mController.onPreferenceChange(
|
mController.onPreferenceChange(
|
||||||
@@ -271,7 +276,6 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
|
||||||
public void onPreferenceChange_listPreferenceIsNull() {
|
public void onPreferenceChange_listPreferenceIsNull() {
|
||||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(null);
|
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(null);
|
||||||
assertFalse(
|
assertFalse(
|
||||||
@@ -280,13 +284,11 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
|
||||||
public void onPreferenceChange_unknownCodecId() {
|
public void onPreferenceChange_unknownCodecId() {
|
||||||
assertFalse(mController.onPreferenceChange(mPreference, String.valueOf(TEST_ENTRY_VALUE)));
|
assertFalse(mController.onPreferenceChange(mPreference, String.valueOf(TEST_ENTRY_VALUE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
|
||||||
public void onPreferenceChange_codecSelection() {
|
public void onPreferenceChange_codecSelection() {
|
||||||
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
|
||||||
when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice))
|
when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice))
|
||||||
@@ -325,6 +327,14 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
assertTrue(
|
assertTrue(
|
||||||
mController.onPreferenceChange(
|
mController.onPreferenceChange(
|
||||||
mPreference, String.valueOf(mCodecTypeAPTX.getCodecId())));
|
mPreference, String.valueOf(mCodecTypeAPTX.getCodecId())));
|
||||||
|
mCodecStatus =
|
||||||
|
new BluetoothCodecStatus.Builder()
|
||||||
|
.setCodecConfig(mCodecConfigAPTXHD)
|
||||||
|
.setCodecsSelectableCapabilities(mCodecConfigs)
|
||||||
|
.build();
|
||||||
|
assertTrue(
|
||||||
|
mController.onPreferenceChange(
|
||||||
|
mPreference, String.valueOf(mCodecTypeAPTXHD.getCodecId())));
|
||||||
mCodecStatus =
|
mCodecStatus =
|
||||||
new BluetoothCodecStatus.Builder()
|
new BluetoothCodecStatus.Builder()
|
||||||
.setCodecConfig(mCodecConfigOPUS)
|
.setCodecConfig(mCodecConfigOPUS)
|
||||||
@@ -336,7 +346,6 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
|
||||||
public void updateState_notifyPreference() {
|
public void updateState_notifyPreference() {
|
||||||
assertFalse(
|
assertFalse(
|
||||||
mController.onPreferenceChange(
|
mController.onPreferenceChange(
|
||||||
@@ -437,7 +446,6 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
|
||||||
public void onBluetoothServiceConnected_verifyBluetoothA2dpConfigStore() {
|
public void onBluetoothServiceConnected_verifyBluetoothA2dpConfigStore() {
|
||||||
mCodecStatus =
|
mCodecStatus =
|
||||||
new BluetoothCodecStatus.Builder()
|
new BluetoothCodecStatus.Builder()
|
||||||
|
|||||||
@@ -22,14 +22,9 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.platform.test.annotations.DisableFlags;
|
|
||||||
import android.platform.test.annotations.EnableFlags;
|
|
||||||
import android.platform.test.flag.junit.SetFlagsRule;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.view.accessibility.Flags;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
@@ -37,8 +32,6 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class OneHandedSettingsUtilsTest {
|
public class OneHandedSettingsUtilsTest {
|
||||||
@Rule
|
|
||||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
|
||||||
private static final int OFF = 0;
|
private static final int OFF = 0;
|
||||||
private static final int ON = 1;
|
private static final int ON = 1;
|
||||||
|
|
||||||
@@ -162,7 +155,6 @@ public class OneHandedSettingsUtilsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT)
|
|
||||||
public void getShortcutEnabled_qsShortcutEnabled_returnTrue() {
|
public void getShortcutEnabled_qsShortcutEnabled_returnTrue() {
|
||||||
setupShortcuts(
|
setupShortcuts(
|
||||||
/* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ true);
|
/* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ true);
|
||||||
@@ -170,15 +162,6 @@ public class OneHandedSettingsUtilsTest {
|
|||||||
assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isTrue();
|
assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT)
|
|
||||||
public void getShortcutEnabled_flagDisabled_qsShortcutEnabled_returnFalse() {
|
|
||||||
setupShortcuts(
|
|
||||||
/* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ true);
|
|
||||||
|
|
||||||
assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupShortcuts(boolean enableFab, boolean enableVolumeKeys, boolean enableQs) {
|
private void setupShortcuts(boolean enableFab, boolean enableVolumeKeys, boolean enableQs) {
|
||||||
setupShortcut(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, enableFab);
|
setupShortcut(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, enableFab);
|
||||||
setupShortcut(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, enableVolumeKeys);
|
setupShortcut(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, enableVolumeKeys);
|
||||||
|
|||||||
Reference in New Issue
Block a user