Add Hearable control slice in bluetooth device detail settings

Bug: 229048602
Test: make -j64 RunSettingsRoboTests
Change-Id: I850aaee9bf7518c9f9de065fbbd1eb4919fc62ee
This commit is contained in:
Alan Huang
2022-05-12 15:47:59 +00:00
parent 56c7f91cea
commit 8595cf779a
5 changed files with 87 additions and 0 deletions

View File

@@ -46,6 +46,11 @@
android:key="action_buttons" android:key="action_buttons"
settings:allowDividerBelow="true"/> settings:allowDividerBelow="true"/>
<com.android.settings.slices.SlicePreference
android:key="bt_extra_control"
settings:controller="com.android.settings.slices.SlicePreferenceController"
settings:allowDividerAbove="true"/>
<com.android.settings.slices.SlicePreference <com.android.settings.slices.SlicePreference
android:key="bt_device_slice" android:key="bt_device_slice"
settings:controller="com.android.settings.slices.BlockingSlicePrefController" settings:controller="com.android.settings.slices.BlockingSlicePrefController"

View File

@@ -22,12 +22,18 @@ import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@@ -36,12 +42,14 @@ import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.BlockingSlicePrefController; import com.android.settings.slices.BlockingSlicePrefController;
import com.android.settings.slices.SlicePreferenceController;
import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.IllegalFormatException;
import java.util.List; import java.util.List;
public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment { public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment {
@@ -61,6 +69,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
@VisibleForTesting @VisibleForTesting
interface TestDataFactory { interface TestDataFactory {
CachedBluetoothDevice getDevice(String deviceAddress); CachedBluetoothDevice getDevice(String deviceAddress);
LocalBluetoothManager getManager(Context context); LocalBluetoothManager getManager(Context context);
} }
@@ -127,6 +136,49 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
use(BlockingSlicePrefController.class).setSliceUri(sliceEnabled use(BlockingSlicePrefController.class).setSliceUri(sliceEnabled
? featureProvider.getBluetoothDeviceSettingsUri(mCachedDevice.getDevice()) ? featureProvider.getBluetoothDeviceSettingsUri(mCachedDevice.getDevice())
: null); : null);
updateExtraControlUri(/* viewWidth */ 0);
}
private void updateExtraControlUri(int viewWidth) {
BluetoothFeatureProvider featureProvider = FeatureFactory.getFactory(
getContext()).getBluetoothFeatureProvider(getContext());
boolean sliceEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
SettingsUIDeviceConfig.BT_SLICE_SETTINGS_ENABLED, true);
Uri controlUri = null;
String uri = featureProvider.getBluetoothDeviceControlUri(mCachedDevice.getDevice());
if (!TextUtils.isEmpty(uri)) {
try {
controlUri = Uri.parse(String.format(uri, viewWidth));
} catch (IllegalFormatException | NullPointerException exception) {
Log.d(TAG, "unable to parse uri");
controlUri = null;
}
}
use(SlicePreferenceController.class).setSliceUri(sliceEnabled ? controlUri : null);
}
private final ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener =
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
View view = getView();
if (view == null) {
return;
}
updateExtraControlUri(view.getWidth());
view.getViewTreeObserver().removeOnGlobalLayoutListener(
mOnGlobalLayoutListener);
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
if (view != null) {
view.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
}
return view;
} }
@Override @Override

View File

@@ -26,8 +26,17 @@ public interface BluetoothFeatureProvider {
/** /**
* Get the {@link Uri} that represents extra settings for a specific bluetooth device * Get the {@link Uri} that represents extra settings for a specific bluetooth device
*
* @param bluetoothDevice bluetooth device * @param bluetoothDevice bluetooth device
* @return {@link Uri} for extra settings * @return {@link Uri} for extra settings
*/ */
Uri getBluetoothDeviceSettingsUri(BluetoothDevice bluetoothDevice); Uri getBluetoothDeviceSettingsUri(BluetoothDevice bluetoothDevice);
/**
* Get the {@link Uri} that represents extra control for a specific bluetooth device
*
* @param bluetoothDevice bluetooth device
* @return {@link String} uri string for extra control
*/
String getBluetoothDeviceControlUri(BluetoothDevice bluetoothDevice);
} }

View File

@@ -20,6 +20,8 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import com.android.settingslib.bluetooth.BluetoothUtils;
/** /**
* Impl of {@link BluetoothFeatureProvider} * Impl of {@link BluetoothFeatureProvider}
*/ */
@@ -37,4 +39,9 @@ public class BluetoothFeatureProviderImpl implements BluetoothFeatureProvider {
BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI); BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI);
return uriByte == null ? null : Uri.parse(new String(uriByte)); return uriByte == null ? null : Uri.parse(new String(uriByte));
} }
@Override
public String getBluetoothDeviceControlUri(BluetoothDevice bluetoothDevice) {
return BluetoothUtils.getControlUriMetaData(bluetoothDevice);
}
} }

View File

@@ -33,6 +33,11 @@ import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class BluetoothFeatureProviderImplTest { public class BluetoothFeatureProviderImplTest {
private static final String SETTINGS_URI = "content://test.provider/settings_uri"; private static final String SETTINGS_URI = "content://test.provider/settings_uri";
private static final String CONTROL_METADATA =
"<HEARABLE_CONTROL_SLICE_WITH_WIDTH>" + SETTINGS_URI
+ "</HEARABLE_CONTROL_SLICE_WITH_WIDTH>";
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
private BluetoothFeatureProvider mBluetoothFeatureProvider; private BluetoothFeatureProvider mBluetoothFeatureProvider;
@Mock @Mock
@@ -54,4 +59,13 @@ public class BluetoothFeatureProviderImplTest {
final Uri uri = mBluetoothFeatureProvider.getBluetoothDeviceSettingsUri(mBluetoothDevice); final Uri uri = mBluetoothFeatureProvider.getBluetoothDeviceSettingsUri(mBluetoothDevice);
assertThat(uri.toString()).isEqualTo(SETTINGS_URI); assertThat(uri.toString()).isEqualTo(SETTINGS_URI);
} }
@Test
public void getBluetoothDeviceControlUri_returnsCorrectUri() {
when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS)).thenReturn(
CONTROL_METADATA.getBytes());
assertThat(
mBluetoothFeatureProvider.getBluetoothDeviceControlUri(mBluetoothDevice)).isEqualTo(
SETTINGS_URI);
}
} }