[VolumePanel] Add Hearable control slice in VolumePanel
Bug: 229048602
Test: make -j64 RunSettingsRoboTests
Change-Id: Ia799a805594803a9a014eef76bb3db5a50a13524
diff --git a/src/com/android/settings/panel/VolumePanel.java b/src/com/android/settings/panel/VolumePanel.java
index e0d8a7f..98939cf 100644
--- a/src/com/android/settings/panel/VolumePanel.java
+++ b/src/com/android/settings/panel/VolumePanel.java
@@ -27,30 +27,43 @@
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_RINGER_URI;
import android.app.settings.SettingsEnums;
+import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import com.android.settings.R;
+import com.android.settings.bluetooth.Utils;
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.media.MediaOutputConstants;
import java.util.ArrayList;
+import java.util.IllegalFormatException;
import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
/**
* Panel data class for Volume settings.
*/
public class VolumePanel implements PanelContent, LifecycleObserver {
+ private static final String TAG = "VolumePanel";
private final Context mContext;
private PanelContentCallback mCallback;
+ private LocalBluetoothProfileManager mProfileManager;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -67,6 +80,21 @@
private VolumePanel(Context context) {
mContext = context.getApplicationContext();
+
+ final FutureTask<LocalBluetoothManager> localBtManagerFutureTask = new FutureTask<>(
+ // Avoid StrictMode ThreadPolicy violation
+ () -> Utils.getLocalBtManager(mContext));
+ LocalBluetoothManager localBluetoothManager;
+ try {
+ localBtManagerFutureTask.run();
+ localBluetoothManager = localBtManagerFutureTask.get();
+ } catch (InterruptedException | ExecutionException e) {
+ Log.w(TAG, "Error getting LocalBluetoothManager.");
+ return;
+ }
+ if (localBluetoothManager != null) {
+ mProfileManager = localBluetoothManager.getProfileManager();
+ }
}
/** Invoked when the panel is resumed. */
@@ -95,6 +123,11 @@
uris.add(REMOTE_MEDIA_SLICE_URI);
uris.add(VOLUME_MEDIA_URI);
+ Uri controlUri = getExtraControlUri();
+ if (controlUri != null) {
+ Log.d(TAG, "add extra control slice");
+ uris.add(controlUri);
+ }
uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI);
uris.add(VOLUME_CALL_URI);
uris.add(VOLUME_RINGER_URI);
@@ -121,4 +154,33 @@
public void registerCallback(PanelContentCallback callback) {
mCallback = callback;
}
+
+ private Uri getExtraControlUri() {
+ Uri controlUri = null;
+ final BluetoothDevice bluetoothDevice = findActiveDevice();
+ if (bluetoothDevice != null) {
+ final int width = mContext.getResources().getDimensionPixelSize(
+ R.dimen.settings_panel_width);
+ final String uri = BluetoothUtils.getControlUriMetaData(bluetoothDevice);
+ if (!TextUtils.isEmpty(uri)) {
+ try {
+ controlUri = Uri.parse(String.format(uri, width));
+ } catch (IllegalFormatException | NullPointerException exception) {
+ Log.d(TAG, "unable to parse uri");
+ controlUri = null;
+ }
+ }
+ }
+ return controlUri;
+ }
+
+ private BluetoothDevice findActiveDevice() {
+ if (mProfileManager != null) {
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ if (a2dpProfile != null) {
+ return a2dpProfile.getActiveDevice();
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file