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

Commit 41f7c222 authored by Haijie Hong's avatar Haijie Hong
Browse files

Rearrange bluetooth device details fragment according to config

BUG: 343317785
Test: atest DeviceDetailsFragmentFormatterTest
Flag: com.android.settings.flags.enable_bluetooth_device_details_polish
Change-Id: I440f85b2c402920e851915ff56fa7b3f5356e807
parent 2a01b356
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -101,7 +101,8 @@ public class BlockingPrefWithSliceController extends BasePreferenceController im
        return mUri != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
    }

    public void setSliceUri(Uri uri) {
    /** Sets Slice uri for the preference. */
    public void setSliceUri(@Nullable Uri uri) {
        mUri = uri;
        mLiveData = SliceLiveData.fromUri(mContext, mUri, (int type, Throwable source) -> {
            Log.w(TAG, "Slice may be null. uri = " + uri + ", error = " + type);
+78 −17
Original line number Diff line number Diff line
@@ -43,10 +43,12 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.settings.R;
import com.android.settings.bluetooth.ui.view.DeviceDetailsFragmentFormatter;
import com.android.settings.connecteddevice.stylus.StylusDevicesController;
import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settings.dashboard.RestrictedDashboardFragment;
@@ -60,9 +62,11 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment {
    public static final String KEY_DEVICE_ADDRESS = "device_address";
@@ -98,6 +102,8 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
    @VisibleForTesting
    CachedBluetoothDevice mCachedDevice;
    BluetoothAdapter mBluetoothAdapter;
    @VisibleForTesting
    DeviceDetailsFragmentFormatter mFormatter;

    @Nullable
    InputDevice mInputDevice;
@@ -214,18 +220,29 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
            finish();
            return;
        }
        use(AdvancedBluetoothDetailsHeaderController.class).init(mCachedDevice, this);
        use(LeAudioBluetoothDetailsHeaderController.class).init(mCachedDevice, mManager, this);
        use(KeyboardSettingsPreferenceController.class).init(mCachedDevice);
        getController(
                AdvancedBluetoothDetailsHeaderController.class,
                controller -> controller.init(mCachedDevice, this));
        getController(
                LeAudioBluetoothDetailsHeaderController.class,
                controller -> controller.init(mCachedDevice, mManager, this));
        getController(
                KeyboardSettingsPreferenceController.class,
                controller -> controller.init(mCachedDevice));

        final BluetoothFeatureProvider featureProvider =
                FeatureFactory.getFeatureFactory().getBluetoothFeatureProvider();
        final boolean sliceEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
                SettingsUIDeviceConfig.BT_SLICE_SETTINGS_ENABLED, true);

        use(BlockingPrefWithSliceController.class).setSliceUri(sliceEnabled
                ? featureProvider.getBluetoothDeviceSettingsUri(mCachedDevice.getDevice())
                : null);
        getController(
                BlockingPrefWithSliceController.class,
                controller ->
                        controller.setSliceUri(
                                sliceEnabled
                                        ? featureProvider.getBluetoothDeviceSettingsUri(
                                                mCachedDevice.getDevice())
                                        : null));

        mManager.getEventManager().registerCallback(mBluetoothCallback);
        mBluetoothAdapter.addOnMetadataChangedListener(
@@ -257,21 +274,35 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
            }
        }
        mExtraControlUriLoaded |= controlUri != null;
        final SlicePreferenceController slicePreferenceController = use(
                SlicePreferenceController.class);
        slicePreferenceController.setSliceUri(sliceEnabled ? controlUri : null);
        slicePreferenceController.onStart();
        slicePreferenceController.displayPreference(getPreferenceScreen());

        Uri finalControlUri = controlUri;
        getController(SlicePreferenceController.class, controller -> {
            controller.setSliceUri(sliceEnabled ? finalControlUri : null);
            controller.onStart();
            controller.displayPreference(getPreferenceScreen());
        });


        // Temporarily fix the issue that the page will be automatically scrolled to a wrong
        // position when entering the page. This will make sure the bluetooth header is shown on top
        // of the page.
        use(LeAudioBluetoothDetailsHeaderController.class).displayPreference(
                getPreferenceScreen());
        use(AdvancedBluetoothDetailsHeaderController.class).displayPreference(
                getPreferenceScreen());
        use(BluetoothDetailsHeaderController.class).displayPreference(
                getPreferenceScreen());
        getController(
                LeAudioBluetoothDetailsHeaderController.class,
                controller -> controller.displayPreference(getPreferenceScreen()));
        getController(
                AdvancedBluetoothDetailsHeaderController.class,
                controller -> controller.displayPreference(getPreferenceScreen()));
        getController(
                BluetoothDetailsHeaderController.class,
                controller -> controller.displayPreference(getPreferenceScreen()));
    }

    protected <T extends AbstractPreferenceController> void getController(Class<T> clazz,
            Consumer<T> action) {
        T controller = use(clazz);
        if (controller != null) {
            action.accept(controller);
        }
    }

    private final ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener =
@@ -308,6 +339,14 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
        return view;
    }

    @Override
    public void onCreatePreferences(@NonNull Bundle savedInstanceState, @NonNull String rootKey) {
        super.onCreatePreferences(savedInstanceState, rootKey);
        if (Flags.enableBluetoothDeviceDetailsPolish()) {
            mFormatter.updateLayout();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
@@ -358,8 +397,30 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
        return super.onOptionsItemSelected(menuItem);
    }

    @Override
    protected void addPreferenceController(AbstractPreferenceController controller) {
        if (Flags.enableBluetoothDeviceDetailsPolish()) {
            List<String> keys = mFormatter.getVisiblePreferenceKeysForMainPage();
            Lifecycle lifecycle = getSettingsLifecycle();
            if (keys == null || keys.contains(controller.getPreferenceKey())) {
                super.addPreferenceController(controller);
            } else if (controller instanceof LifecycleObserver) {
                lifecycle.removeObserver((LifecycleObserver) controller);
            }
        } else {
            super.addPreferenceController(controller);
        }
    }

    @Override
    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
        if (Flags.enableBluetoothDeviceDetailsPolish()) {
            mFormatter =
                    FeatureFactory.getFeatureFactory()
                            .getBluetoothFeatureProvider()
                            .getDeviceDetailsFragmentFormatter(
                                    requireContext(), this, mBluetoothAdapter, mCachedDevice);
        }
        ArrayList<AbstractPreferenceController> controllers = new ArrayList<>();

        if (mCachedDevice != null) {
+21 −0
Original line number Diff line number Diff line
@@ -16,15 +16,21 @@

package com.android.settings.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.media.Spatializer;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleCoroutineScope;
import androidx.preference.Preference;

import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.bluetooth.ui.view.DeviceDetailsFragmentFormatter;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.devicesettings.data.repository.DeviceSettingRepository;

import java.util.List;
import java.util.Set;
@@ -84,4 +90,19 @@ public interface BluetoothFeatureProvider {
     */
    Set<String> getInvisibleProfilePreferenceKeys(
            Context context, BluetoothDevice bluetoothDevice);

    /** Gets DeviceSettingRepository. */
    @NonNull
    DeviceSettingRepository getDeviceSettingRepository(
            @NonNull Context context,
            @NonNull BluetoothAdapter bluetoothAdapter,
            @NonNull LifecycleCoroutineScope scope);

    /** Gets device details fragment layout formatter. */
    @NonNull
    DeviceDetailsFragmentFormatter getDeviceDetailsFragmentFormatter(
            @NonNull Context context,
            @NonNull SettingsPreferenceFragment fragment,
            @NonNull BluetoothAdapter bluetoothAdapter,
            @NonNull CachedBluetoothDevice cachedDevice);
}
+29 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.settings.bluetooth;

import static com.android.settings.bluetooth.utils.DeviceSettingUtilsKt.createDeviceSettingRepository;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
@@ -23,10 +26,16 @@ import android.media.AudioManager;
import android.media.Spatializer;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleCoroutineScope;
import androidx.preference.Preference;

import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.bluetooth.ui.view.DeviceDetailsFragmentFormatter;
import com.android.settings.bluetooth.ui.view.DeviceDetailsFragmentFormatterImpl;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.devicesettings.data.repository.DeviceSettingRepository;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -73,4 +82,24 @@ public class BluetoothFeatureProviderImpl implements BluetoothFeatureProvider {
            Context context, BluetoothDevice bluetoothDevice) {
        return ImmutableSet.of();
    }

    @Override
    @NonNull
    public DeviceSettingRepository getDeviceSettingRepository(
            @NonNull Context context,
            @NonNull BluetoothAdapter bluetoothAdapter,
            @NonNull LifecycleCoroutineScope scope) {
        return createDeviceSettingRepository(context, bluetoothAdapter, scope);
    }

    @Override
    @NonNull
    public DeviceDetailsFragmentFormatter getDeviceDetailsFragmentFormatter(
            @NonNull Context context,
            @NonNull SettingsPreferenceFragment fragment,
            @NonNull BluetoothAdapter bluetoothAdapter,
            @NonNull CachedBluetoothDevice cachedDevice) {
        return new DeviceDetailsFragmentFormatterImpl(
                context, fragment, bluetoothAdapter, cachedDevice);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.settings.bluetooth.ui
package com.android.settings.bluetooth.ui.composable

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
Loading