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

Commit 8b2b9d3b authored by William Escande's avatar William Escande
Browse files

ScanMode: Stop writing ScanMode in config

The scan mode is erased when the stack shutdown, and it is force
overwrite when the stack start. It serve no purpose to write it on disk.
Prior to this, turning off the stack is generating a config change and
it is slowing down the shutdown, especially on slow disk hardware

Bug: 310147428
Test: atest BluetoothInstrumentationTests:AdapterServiceTest
Flag: Exempt refactor
Change-Id: I405d973f8ce9bbfbd35fff0a4aab2da8bcf54203
parent d9017723
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1541,6 +1541,16 @@ static jboolean sspReplyNative(JNIEnv* env, jobject /* obj */,
  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setScanModeNative(JNIEnv* /* env */, jobject /* obj */,
                                  jint mode) {
  log::verbose("");

  if (!sBluetoothInterface) return JNI_FALSE;

  sBluetoothInterface->set_scan_mode((bt_scan_mode_t)mode);
  return JNI_TRUE;
}

static jboolean setAdapterPropertyNative(JNIEnv* env, jobject /* obj */,
                                         jint type, jbyteArray value) {
  log::verbose("");
@@ -2144,6 +2154,7 @@ int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
      {"cleanupNative", "()V", (void*)cleanupNative},
      {"enableNative", "()Z", (void*)enableNative},
      {"disableNative", "()Z", (void*)disableNative},
      {"setScanModeNative", "(I)Z", (void*)setScanModeNative},
      {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative},
      {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative},
      {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative},
+1 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.bluetooth.btservice;

public final class AbstractionLayer {
    // Do not modify without updating the HAL files.
    // Do not modify without migrating data in the config

    // TODO: Some of the constants are repeated from BluetoothAdapter.java.
    // Get rid of them and maintain just one.
@@ -34,7 +35,6 @@ public final class AbstractionLayer {
    static final int BT_PROPERTY_CLASS_OF_DEVICE = 0x04;
    static final int BT_PROPERTY_TYPE_OF_DEVICE = 0x05;
    static final int BT_PROPERTY_SERVICE_RECORD = 0x06;
    static final int BT_PROPERTY_ADAPTER_SCAN_MODE = 0x07;
    static final int BT_PROPERTY_ADAPTER_BONDED_DEVICES = 0x08;
    static final int BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT = 0x09;

+6 −0
Original line number Diff line number Diff line
@@ -89,6 +89,10 @@ public class AdapterNativeInterface {
        return disableNative();
    }

    boolean setScanMode(int mode) {
        return setScanModeNative(mode);
    }

    boolean setAdapterProperty(int type, byte[] val) {
        return setAdapterPropertyNative(type, val);
    }
@@ -283,6 +287,8 @@ public class AdapterNativeInterface {

    private native boolean disableNative();

    private native boolean setScanModeNative(int mode);

    private native boolean setAdapterPropertyNative(int type, byte[] val);

    private native boolean getAdapterPropertiesNative();
+0 −77
Original line number Diff line number Diff line
@@ -63,8 +63,6 @@ import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
import com.android.bluetooth.flags.Flags;
import com.android.modules.utils.build.SdkLevel;

import com.google.common.collect.EvictingQueue;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -100,9 +98,6 @@ class AdapterProperties {
    private CopyOnWriteArrayList<BluetoothDevice> mBondedDevices =
            new CopyOnWriteArrayList<BluetoothDevice>();

    private static final int SCAN_MODE_CHANGES_MAX_SIZE = 10;
    private EvictingQueue<String> mScanModeChanges;

    private int mProfilesConnecting, mProfilesConnected, mProfilesDisconnecting;
    private final HashMap<Integer, Pair<Integer, Integer>> mProfileConnectionState =
            new HashMap<>();
@@ -220,7 +215,6 @@ class AdapterProperties {
    AdapterProperties(AdapterService service) {
        mService = service;
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mScanModeChanges = EvictingQueue.create(SCAN_MODE_CHANGES_MAX_SIZE);
        invalidateBluetoothCaches();
    }

@@ -290,7 +284,6 @@ class AdapterProperties {
        }
        mService = null;
        mBondedDevices.clear();
        mScanModeChanges.clear();
        invalidateBluetoothCaches();
    }

@@ -351,38 +344,6 @@ class AdapterProperties {
        }
    }

    /**
     * @return the mScanMode
     */
    int getScanMode() {
        return mScanMode;
    }

    /**
     * Set the local adapter property - scanMode
     *
     * @param scanMode the ScanMode to set, valid values are: { BluetoothAdapter.SCAN_MODE_NONE,
     *     BluetoothAdapter.SCAN_MODE_CONNECTABLE,
     *     BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, }
     */
    boolean setScanMode(int scanMode) {
        addScanChangeLog(scanMode);
        synchronized (mObject) {
            return mService.getNative()
                    .setAdapterProperty(
                            AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE,
                            Utils.intToByteArray(AdapterService.convertScanModeToHal(scanMode)));
        }
    }

    private void addScanChangeLog(int scanMode) {
        String time = Utils.getLocalTimeString();
        String uidPid = Utils.getUidPidString();
        String scanModeString = dumpScanMode(scanMode);

        mScanModeChanges.add(time + " (" + uidPid + ") " + scanModeString);
    }

    /**
     * @return the mUuids
     */
@@ -1017,16 +978,6 @@ class AdapterProperties {
                        }
                        debugLog("BT Class:" + mBluetoothClass);
                        break;
                    case AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE:
                        int mode = Utils.byteArrayToInt(val, 0);
                        mScanMode = AdapterService.convertScanModeFromHal(mode);
                        intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
                        intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mScanMode);
                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                        mService.sendBroadcast(
                                intent, BLUETOOTH_SCAN, Utils.getTempBroadcastOptions().toBundle());
                        debugLog("Scan Mode:" + mScanMode);
                        break;
                    case AbstractionLayer.BT_PROPERTY_UUIDS:
                        mUuids = Utils.byteArrayToUuid(val);
                        break;
@@ -1184,20 +1135,11 @@ class AdapterProperties {
            mProfilesConnected = 0;
            mProfilesConnecting = 0;
            mProfilesDisconnecting = 0;
            // adapterPropertyChangedCallback has already been received.  Set the scan mode.
            setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
            // This keeps NV up-to date on first-boot after flash.
            setDiscoverableTimeout(mDiscoverableTimeout);
        }
    }

    void onBleDisable() {
        // Sequence BLE_ON to STATE_OFF - that is _complete_ OFF state.
        debugLog("onBleDisable");
        // Set the scan_mode to NONE (no incoming connections).
        setScanMode(BluetoothAdapter.SCAN_MODE_NONE);
    }

    void discoveryStateChangeCallback(int state) {
        infoLog("Callback:discoveryStateChangeCallback with state:" + state);
        synchronized (mObject) {
@@ -1236,7 +1178,6 @@ class AdapterProperties {
        writer.println(TAG);
        writer.println("  " + "Name: " + getName());
        writer.println("  " + "Address: " + Utils.getAddressStringFromByte(mAddress));
        writer.println("  " + "ScanMode: " + dumpScanMode(getScanMode()));
        writer.println("  " + "ConnectionState: " + dumpConnectionState(getConnectionState()));
        writer.println("  " + "State: " + BluetoothAdapter.nameForState(getState()));
        writer.println("  " + "MaxConnectedAudioDevices: " + getMaxConnectedAudioDevices());
@@ -1280,11 +1221,6 @@ class AdapterProperties {
            }
        }
        writer.println(sb.toString());

        writer.println("  " + "Scan Mode Changes:");
        for (String log : mScanModeChanges) {
            writer.println("    " + log);
        }
    }

    private String dumpDeviceType(int deviceType) {
@@ -1317,19 +1253,6 @@ class AdapterProperties {
        }
    }

    private String dumpScanMode(int scanMode) {
        switch (scanMode) {
            case BluetoothAdapter.SCAN_MODE_NONE:
                return "SCAN_MODE_NONE";
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
                return "SCAN_MODE_CONNECTABLE";
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                return "SCAN_MODE_CONNECTABLE_DISCOVERABLE";
            default:
                return "Unknown Scan Mode " + scanMode;
        }
    }

    private static void infoLog(String msg) {
        Log.i(TAG, msg);
    }
+68 −15
Original line number Diff line number Diff line
@@ -17,6 +17,10 @@

package com.android.bluetooth.btservice;

import static android.Manifest.permission.BLUETOOTH_SCAN;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
import static android.bluetooth.BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
import static android.bluetooth.BluetoothDevice.TRANSPORT_AUTO;
import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
@@ -158,6 +162,7 @@ import com.android.modules.utils.BytesMatcher;
import libcore.util.SneakyThrow;

import com.google.common.base.Ascii;
import com.google.common.collect.EvictingQueue;
import com.google.protobuf.InvalidProtocolBufferException;

import java.io.FileDescriptor;
@@ -176,6 +181,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
@@ -251,6 +257,8 @@ public class AdapterService extends Service {
    private final RemoteCallbackList<IBluetoothCallback> mRemoteCallbacks =
            new RemoteCallbackList<>();

    private final EvictingQueue<String> mScanModeChanges = EvictingQueue.create(10);

    private final DeviceConfigListener mDeviceConfigListener = new DeviceConfigListener();

    private final Looper mLooper;
@@ -326,6 +334,8 @@ public class AdapterService extends Service {
    /** Handlers for incoming service calls */
    private AdapterServiceBinder mBinder;

    private volatile int mScanMode;

    // Report ID definition
    public enum BqrQualityReportId {
        QUALITY_REPORT_ID_MONITOR_MODE(0x01),
@@ -529,6 +539,7 @@ public class AdapterService extends Service {
                    } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
                            && mRegisteredProfiles.size() == mRunningProfiles.size()) {
                        mAdapterProperties.onBluetoothReady();
                        setScanMode(SCAN_MODE_CONNECTABLE, "processProfileServiceStateChanged");
                        updateUuids();
                        initProfileServices();
                        mNativeInterface.getAdapterProperty(
@@ -1059,6 +1070,7 @@ public class AdapterService extends Service {
            // This will check other profile services.
            if (supportedProfileServices.length == 0) {
                mAdapterProperties.onBluetoothReady();
                setScanMode(SCAN_MODE_CONNECTABLE, "startProfileServices");
                updateUuids();
                mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
            } else {
@@ -1071,6 +1083,7 @@ public class AdapterService extends Service {
            if (supportedProfileServices.length == 1
                    && supportedProfileServices[0] == BluetoothProfile.GATT) {
                mAdapterProperties.onBluetoothReady();
                setScanMode(SCAN_MODE_CONNECTABLE, "startProfileServices");
                updateUuids();
                mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
            } else {
@@ -1082,7 +1095,7 @@ public class AdapterService extends Service {
    void stopProfileServices() {
        // Make sure to stop classic background tasks now
        mNativeInterface.cancelDiscovery();
        mAdapterProperties.setScanMode(BluetoothAdapter.SCAN_MODE_NONE);
        setScanMode(SCAN_MODE_NONE, "StopProfileServices");

        int[] supportedProfileServices = Config.getSupportedProfiles();
        if (Flags.scanManagerRefactor()) {
@@ -1127,7 +1140,8 @@ public class AdapterService extends Service {
    }

    private void stopGattProfileService() {
        mAdapterProperties.onBleDisable();
        setScanMode(SCAN_MODE_NONE, "stopGattProfileService");

        if (mRunningProfiles.size() == 0) {
            Log.d(TAG, "stopGattProfileService() - No profiles services to stop.");
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
@@ -1146,7 +1160,7 @@ public class AdapterService extends Service {
    }

    private void stopScanController() {
        mAdapterProperties.onBleDisable();
        setScanMode(SCAN_MODE_NONE, "stopScanController");

        if (mScanController == null) {
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
@@ -2471,7 +2485,7 @@ public class AdapterService extends Service {
                    || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode")
                    || !Utils.checkScanPermissionForDataDelivery(
                            service, attributionSource, "AdapterService getScanMode")) {
                return BluetoothAdapter.SCAN_MODE_NONE;
                return SCAN_MODE_NONE;
            }

            return service.getScanMode();
@@ -2488,7 +2502,15 @@ public class AdapterService extends Service {
            }
            enforceBluetoothPrivilegedPermission(service);

            return service.mAdapterProperties.setScanMode(mode)
            String logCaller =
                    Utils.getUidPidString() + " packageName=" + attributionSource.getPackageName();
            CompletableFuture<Boolean> future = new CompletableFuture<>();
            mService.mHandler.post(
                    () ->
                            future.complete(
                                    service.getState() == BluetoothAdapter.STATE_ON
                                            && service.setScanMode(mode, logCaller)));
            return future.join()
                    ? BluetoothStatusCodes.SUCCESS
                    : BluetoothStatusCodes.ERROR_UNKNOWN;
        }
@@ -4169,7 +4191,6 @@ public class AdapterService extends Service {
            return BluetoothStatusCodes.SUCCESS;
        }

        @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
        @Override
        public int getOffloadedTransportDiscoveryDataScanSupported(
                AttributionSource attributionSource) {
@@ -5859,7 +5880,21 @@ public class AdapterService extends Service {

    @VisibleForTesting
    int getScanMode() {
        return mAdapterProperties.getScanMode();
        return mScanMode;
    }

    private boolean setScanMode(int mode, String from) {
        mScanModeChanges.add(Utils.getLocalTimeString() + " (" + from + ") " + dumpScanMode(mode));
        if (!mNativeInterface.setScanMode(convertScanModeToHal(mode))) {
            return false;
        }
        mScanMode = mode;
        Intent intent =
                new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)
                        .putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mScanMode)
                        .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        sendBroadcast(intent, BLUETOOTH_SCAN, Utils.getTempBroadcastOptions().toBundle());
        return true;
    }

    @VisibleForTesting
@@ -6093,27 +6128,25 @@ public class AdapterService extends Service {

    static int convertScanModeToHal(int mode) {
        switch (mode) {
            case BluetoothAdapter.SCAN_MODE_NONE:
            case SCAN_MODE_NONE:
                return AbstractionLayer.BT_SCAN_MODE_NONE;
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
            case SCAN_MODE_CONNECTABLE:
                return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE;
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
            case SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
        }
        // Log.e(TAG, "Incorrect scan mode in convertScanModeToHal");
        return -1;
    }

    static int convertScanModeFromHal(int mode) {
        switch (mode) {
            case AbstractionLayer.BT_SCAN_MODE_NONE:
                return BluetoothAdapter.SCAN_MODE_NONE;
                return SCAN_MODE_NONE;
            case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE:
                return BluetoothAdapter.SCAN_MODE_CONNECTABLE;
                return SCAN_MODE_CONNECTABLE;
            case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
                return SCAN_MODE_CONNECTABLE_DISCOVERABLE;
        }
        // Log.e(TAG, "Incorrect scan mode in convertScanModeFromHal");
        return -1;
    }

@@ -6287,6 +6320,19 @@ public class AdapterService extends Service {
        return mRemoteDevices;
    }

    private String dumpScanMode(int scanMode) {
        switch (scanMode) {
            case SCAN_MODE_NONE:
                return "SCAN_MODE_NONE";
            case SCAN_MODE_CONNECTABLE:
                return "SCAN_MODE_CONNECTABLE";
            case SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                return "SCAN_MODE_CONNECTABLE_DISCOVERABLE";
            default:
                return "Unknown Scan Mode " + scanMode;
        }
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        if (args.length == 0) {
@@ -6312,6 +6358,13 @@ public class AdapterService extends Service {

        writer.println();
        mAdapterProperties.dump(fd, writer, args);

        writer.println("ScanMode: " + dumpScanMode(getScanMode()));
        writer.println("Scan Mode Changes:");
        for (String log : mScanModeChanges) {
            writer.println("    " + log);
        }
        writer.println();
        writer.println("sSnoopLogSettingAtEnable = " + sSnoopLogSettingAtEnable);
        writer.println("sDefaultSnoopLogSettingAtEnable = " + sDefaultSnoopLogSettingAtEnable);

Loading