Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a823a2c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add Hearable control slice in bluetooth device detail settings" into tm-dev

parents cd2d6f3e 8595cf77
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -46,6 +46,11 @@
        android:key="action_buttons"
        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
        android:key="bt_device_slice"
        settings:controller="com.android.settings.slices.BlockingSlicePrefController"
+52 −0
Original line number Diff line number Diff line
@@ -22,12 +22,18 @@ import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import androidx.annotation.VisibleForTesting;

@@ -36,12 +42,14 @@ import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.BlockingSlicePrefController;
import com.android.settings.slices.SlicePreferenceController;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;

import java.util.ArrayList;
import java.util.IllegalFormatException;
import java.util.List;

public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment {
@@ -61,6 +69,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
    @VisibleForTesting
    interface TestDataFactory {
        CachedBluetoothDevice getDevice(String deviceAddress);

        LocalBluetoothManager getManager(Context context);
    }

@@ -127,6 +136,49 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
        use(BlockingSlicePrefController.class).setSliceUri(sliceEnabled
                ? featureProvider.getBluetoothDeviceSettingsUri(mCachedDevice.getDevice())
                : 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
+9 −0
Original line number Diff line number Diff line
@@ -26,8 +26,17 @@ public interface BluetoothFeatureProvider {

    /**
     * Get the {@link Uri} that represents extra settings for a specific bluetooth device
     *
     * @param bluetoothDevice bluetooth device
     * @return {@link Uri} for extra settings
     */
    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);
}
+7 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.net.Uri;

import com.android.settingslib.bluetooth.BluetoothUtils;

/**
 * Impl of {@link BluetoothFeatureProvider}
 */
@@ -37,4 +39,9 @@ public class BluetoothFeatureProviderImpl implements BluetoothFeatureProvider {
                BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI);
        return uriByte == null ? null : Uri.parse(new String(uriByte));
    }

    @Override
    public String getBluetoothDeviceControlUri(BluetoothDevice bluetoothDevice) {
        return BluetoothUtils.getControlUriMetaData(bluetoothDevice);
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -33,6 +33,11 @@ import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class BluetoothFeatureProviderImplTest {
    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;

    @Mock
@@ -54,4 +59,13 @@ public class BluetoothFeatureProviderImplTest {
        final Uri uri = mBluetoothFeatureProvider.getBluetoothDeviceSettingsUri(mBluetoothDevice);
        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);
    }
}