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

Commit df4d7182 authored by Sal Savage's avatar Sal Savage
Browse files

Migrate Config.java to use the new *.isEnabled() functions

This change moves determination of whether we should start a profile or
not over to the individual profile level isEnabled() functions. These
functions all use the sysprops internally to return if the profiles
themselves think they should be started/enabled/supported or not.

Tag: #refactor
Bug: 217448211
Test: atest BluetoothInstrumentationTests
Merged-In: Id725b36c2a8975b3c1d0fc60a4e22b302d29bfc4
Change-Id: Id725b36c2a8975b3c1d0fc60a4e22b302d29bfc4
parent ca5a3e54
Loading
Loading
Loading
Loading
+71 −138
Original line number Diff line number Diff line
@@ -17,15 +17,8 @@
package com.android.bluetooth.btservice;

import android.bluetooth.BluetoothProfile;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.os.SystemConfigManager;
import android.os.SystemProperties;
import android.provider.Settings;
import android.sysprop.BluetoothProperties;
import android.text.TextUtils;
import android.util.Log;

import com.android.bluetooth.R;
@@ -54,6 +47,7 @@ import com.android.bluetooth.pbapclient.PbapClientService;
import com.android.bluetooth.sap.SapService;
import com.android.bluetooth.tbs.TbsService;
import com.android.bluetooth.vc.VolumeControlService;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.Arrays;
@@ -78,12 +72,12 @@ public class Config {

    private static class ProfileConfig {
        Class mClass;
        int mSupported;
        boolean mSupported;
        long mMask;

        ProfileConfig(Class theClass, int supportedFlag, long mask) {
        ProfileConfig(Class theClass, boolean supported, long mask) {
            mClass = theClass;
            mSupported = supportedFlag;
            mSupported = supported;
            mMask = mask;
        }
    }
@@ -101,109 +95,96 @@ public class Config {
     * List of profile services with the profile-supported resource flag and bit mask.
     */
    private static final ProfileConfig[] PROFILE_SERVICES_AND_FLAGS = {
            new ProfileConfig(HeadsetService.class, R.bool.profile_supported_hs_hfp,
                    (1 << BluetoothProfile.HEADSET)),
            new ProfileConfig(A2dpService.class, R.bool.profile_supported_a2dp,
            new ProfileConfig(A2dpService.class, A2dpService.isEnabled(),
                    (1 << BluetoothProfile.A2DP)),
            new ProfileConfig(A2dpSinkService.class, R.bool.profile_supported_a2dp_sink,
            new ProfileConfig(A2dpSinkService.class, A2dpSinkService.isEnabled(),
                    (1 << BluetoothProfile.A2DP_SINK)),
            new ProfileConfig(HidHostService.class, R.bool.profile_supported_hid_host,
            new ProfileConfig(AvrcpTargetService.class, AvrcpTargetService.isEnabled(),
                    (1 << BluetoothProfile.AVRCP)),
            new ProfileConfig(AvrcpControllerService.class, AvrcpControllerService.isEnabled(),
                    (1 << BluetoothProfile.AVRCP_CONTROLLER)),
            new ProfileConfig(BassClientService.class, BassClientService.isEnabled(),
                    (1 >> BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)),
            new ProfileConfig(BatteryService.class, BatteryService.isEnabled(),
                    (1 << BluetoothProfile.BATTERY)),
            new ProfileConfig(CsipSetCoordinatorService.class,
                    CsipSetCoordinatorService.isEnabled(),
                    (1 << BluetoothProfile.CSIP_SET_COORDINATOR)),
            new ProfileConfig(HapClientService.class, HapClientService.isEnabled(),
                    (1 << BluetoothProfile.HAP_CLIENT)),
            new ProfileConfig(HeadsetService.class, HeadsetService.isEnabled(),
                    (1 << BluetoothProfile.HEADSET)),
            new ProfileConfig(HeadsetClientService.class, HeadsetClientService.isEnabled(),
                    (1 << BluetoothProfile.HEADSET_CLIENT)),
            new ProfileConfig(HearingAidService.class, HearingAidService.isEnabled(),
                    (1 << BluetoothProfile.HEARING_AID)),
            new ProfileConfig(HidDeviceService.class, HidDeviceService.isEnabled(),
                    (1 << BluetoothProfile.HID_DEVICE)),
            new ProfileConfig(HidHostService.class, HidHostService.isEnabled(),
                    (1 << BluetoothProfile.HID_HOST)),
            new ProfileConfig(PanService.class, R.bool.profile_supported_pan,
                    (1 << BluetoothProfile.PAN)),
            new ProfileConfig(GattService.class, R.bool.profile_supported_gatt,
            new ProfileConfig(GattService.class, GattService.isEnabled(),
                    (1 << BluetoothProfile.GATT)),
            new ProfileConfig(BluetoothMapService.class, R.bool.profile_supported_map,
            new ProfileConfig(LeAudioService.class, LeAudioService.isEnabled(),
                    (1 << BluetoothProfile.LE_AUDIO)),
            new ProfileConfig(TbsService.class, TbsService.isEnabled(),
                    (1 << BluetoothProfile.LE_CALL_CONTROL)),
            new ProfileConfig(BluetoothMapService.class, BluetoothMapService.isEnabled(),
                    (1 << BluetoothProfile.MAP)),
            new ProfileConfig(HeadsetClientService.class, R.bool.profile_supported_hfpclient,
                    (1 << BluetoothProfile.HEADSET_CLIENT)),
            new ProfileConfig(AvrcpTargetService.class, R.bool.profile_supported_avrcp_target,
                    (1 << BluetoothProfile.AVRCP)),
            new ProfileConfig(AvrcpControllerService.class,
                    R.bool.profile_supported_avrcp_controller,
                    (1 << BluetoothProfile.AVRCP_CONTROLLER)),
            new ProfileConfig(SapService.class, R.bool.profile_supported_sap,
                    (1 << BluetoothProfile.SAP)),
            new ProfileConfig(PbapClientService.class, R.bool.profile_supported_pbapclient,
                    (1 << BluetoothProfile.PBAP_CLIENT)),
            new ProfileConfig(MapClientService.class, R.bool.profile_supported_mapmce,
            new ProfileConfig(MapClientService.class, MapClientService.isEnabled(),
                    (1 << BluetoothProfile.MAP_CLIENT)),
            new ProfileConfig(HidDeviceService.class, R.bool.profile_supported_hid_device,
                    (1 << BluetoothProfile.HID_DEVICE)),
            new ProfileConfig(BluetoothOppService.class, R.bool.profile_supported_opp,
            new ProfileConfig(McpService.class, McpService.isEnabled(),
                    (1 << BluetoothProfile.MCP_SERVER)),
            new ProfileConfig(BluetoothOppService.class, BluetoothOppService.isEnabled(),
                    (1 << BluetoothProfile.OPP)),
            new ProfileConfig(BluetoothPbapService.class, R.bool.profile_supported_pbap,
            new ProfileConfig(PanService.class, PanService.isEnabled(),
                    (1 << BluetoothProfile.PAN)),
            new ProfileConfig(BluetoothPbapService.class, BluetoothPbapService.isEnabled(),
                    (1 << BluetoothProfile.PBAP)),
            new ProfileConfig(VolumeControlService.class, R.bool.profile_supported_vc,
            new ProfileConfig(PbapClientService.class, PbapClientService.isEnabled(),
                    (1 << BluetoothProfile.PBAP_CLIENT)),
            new ProfileConfig(SapService.class, SapService.isEnabled(),
                    (1 << BluetoothProfile.SAP)),
            new ProfileConfig(VolumeControlService.class, VolumeControlService.isEnabled(),
                    (1 << BluetoothProfile.VOLUME_CONTROL)),
            new ProfileConfig(McpService.class, R.bool.profile_supported_mcp_server,
                    (1 << BluetoothProfile.MCP_SERVER)),
            new ProfileConfig(TbsService.class, R.bool.profile_supported_le_call_control,
                    (1 << BluetoothProfile.LE_CALL_CONTROL)),
            new ProfileConfig(HearingAidService.class,
                    -1,
                    (1 << BluetoothProfile.HEARING_AID)),
            new ProfileConfig(LeAudioService.class, R.bool.profile_supported_le_audio,
                    (1 << BluetoothProfile.LE_AUDIO)),
            new ProfileConfig(CsipSetCoordinatorService.class,
                    R.bool.profile_supported_csip_set_coordinator,
                    (1 << BluetoothProfile.CSIP_SET_COORDINATOR)),
            new ProfileConfig(HapClientService.class, R.bool.profile_supported_hap_client,
                    (1 << BluetoothProfile.HAP_CLIENT)),
            new ProfileConfig(BassClientService.class,
                    R.bool.profile_supported_bass_client,
                    (1 << BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)),
            new ProfileConfig(BatteryService.class, R.bool.profile_supported_battery,
                    (1 << BluetoothProfile.BATTERY)),
    };

    private static Class[] sSupportedProfiles = new Class[0];

    private static boolean sIsGdEnabledUptoScanningLayer = false;

    static void init(Context ctx) {
        if (ctx == null) {
    /**
     * A test function to allow for dynamic enabled
     */
    @VisibleForTesting
    public static void setProfileEnabled(Class profileClass, boolean enabled) {
        if (profileClass == null) {
            return;
        }
        Resources resources = ctx.getResources();
        if (resources == null) {
            return;
        for (ProfileConfig profile : PROFILE_SERVICES_AND_FLAGS) {
            if (profileClass.equals(profile.mClass)) {
                profile.mSupported = enabled;
            }
        List<String> enabledProfiles = getSystemConfigEnabledProfilesForPackage(ctx);

        ArrayList<Class> profiles = new ArrayList<>(PROFILE_SERVICES_AND_FLAGS.length);
        for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) {
            boolean supported = false;
            if (config.mClass == HearingAidService.class) {
                supported =
                        BluetoothProperties.isProfileAshaCentralEnabled().orElse(false);
            } else {
                supported = config.mSupported > 0 ? resources.getBoolean(config.mSupported) : false;
        }

            if (!supported && (config.mClass == HearingAidService.class)
                    && isFeatureEnabled(ctx, FEATURE_HEARING_AID, /*defaultValue=*/false)) {
                Log.i(TAG, "Feature Flag enables support for HearingAidService");
                supported = true;
    }

            if (config.mClass == BatteryService.class) {
                // It could be overridden by flag.
                supported = isFeatureEnabled(ctx, FEATURE_BATTERY, /*defaultValue=*/ supported);
            }
    private static Class[] sSupportedProfiles = new Class[0];

            if (enabledProfiles != null && enabledProfiles.contains(config.mClass.getName())) {
                supported = true;
                Log.i(TAG, config.mClass.getSimpleName() + " Feature Flag set to " + supported
                        + " by components configuration");
            }
    private static boolean sIsGdEnabledUptoScanningLayer = false;

            if (supported && !isProfileDisabled(ctx, config.mMask)) {
                Log.i(TAG, "Adding " + config.mClass.getSimpleName());
    static void init(Context ctx) {
        ArrayList<Class> profiles = new ArrayList<>(PROFILE_SERVICES_AND_FLAGS.length);
        for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) {
            Log.i(TAG, "init: profile=" + config.mClass.getSimpleName() + ", enabled="
                    + config.mSupported);
            if (config.mSupported) {
                profiles.add(config.mClass);
            }
        }
        sSupportedProfiles = profiles.toArray(new Class[profiles.size()]);

        if (ctx == null) {
            return;
        }
        Resources resources = ctx.getResources();
        if (resources == null) {
            return;
        }
        sIsGdEnabledUptoScanningLayer = resources.getBoolean(R.bool.enable_gd_up_to_scanning_layer);
    }

@@ -255,52 +236,4 @@ public class Config {
        }
        return mask;
    }

    private static boolean isProfileDisabled(Context context, long profileMask) {
        final ContentResolver resolver = context.getContentResolver();
        final long disabledProfilesBitMask =
                Settings.Global.getLong(resolver, Settings.Global.BLUETOOTH_DISABLED_PROFILES, 0);

        return (disabledProfilesBitMask & profileMask) != 0;
    }

    private static boolean isFeatureEnabled(Context context, String feature, boolean defaultValue) {
        // Override precedence:
        // Settings.Global -> [persist.]sys.fflag.override.* -> static list

        // Step 1: check if feature flag is set in Settings.Global.
        String value;
        if (context != null) {
            value = Settings.Global.getString(context.getContentResolver(), feature);
            if (!TextUtils.isEmpty(value)) {
                return Boolean.parseBoolean(value);
            }
        }

        // Step 2: check if feature flag has any override.
        // Flag name: [persist.]sys.fflag.override.<feature>
        value = SystemProperties.get(getSystemPropertyPrefix(feature) + feature);
        if (!TextUtils.isEmpty(value)) {
            return Boolean.parseBoolean(value);
        }
        // Step 3: return default value
        return defaultValue;
    }

    private static String getSystemPropertyPrefix(String feature) {
        return PERSISTENT_FLAGS.contains(feature) ? PERSIST_PREFIX : FFLAG_OVERRIDE_PREFIX;
    }

    private static List<String> getSystemConfigEnabledProfilesForPackage(Context ctx) {
        SystemConfigManager systemConfigManager = ctx.getSystemService(SystemConfigManager.class);
        if (systemConfigManager == null) {
            return null;
        }
        List<String> enabledComponent = new ArrayList<>();
        for (ComponentName comp :
                systemConfigManager.getEnabledComponentOverrides(ctx.getPackageName())) {
            enabledComponent.add(comp.getClassName());
        }
        return enabledComponent;
    }
}
+101 −102

File changed.

Preview size limit exceeded, changes collapsed.