首页 > 其他分享 >Android14 蓝牙启动流程

Android14 蓝牙启动流程

时间:2024-09-21 19:21:32浏览次数:13  
标签:AdapterService enable 流程 BluetoothAdapter 蓝牙 private Android14 boolean

Android14 蓝牙启动流程

文章目录

一、前言

基于Android14 分析了一下蓝牙的开启流程,本来以为比较简单的,但是发现具体处理会有点绕。
主要是从应用上层到cpp层蓝牙的开启过程代码进行的一定的分析。
BluetoothAdapter、BluetoothManagerService、AdapterService 是蓝牙开启最相关的上层代码。

这里记录一下,本文的代码都是基于Android14 讲解的,有兴趣的可以收藏看看。

这个对蓝牙开启失败、或者蓝牙其他流程有问题有一定的分析研究价值,有助于确定是哪个流程出现了问题。

二、流程

从应用把蓝牙开关控制的代码到底层流程进行分析。
从应用app层的enable 到cpp调用的地方。
如果不想细看每个类的主要相关代码,直接看后面总结流程就行。

1、系统应用控制蓝牙开关

//BluetoothAdapter 的获取
BluetoothAdapter bluetoothAdapter= BluetoothAdapter.getDefaultAdapter();

//开启蓝牙
bluetoothAdapter.enable();

需要系统应用和对应的蓝牙权限才能调用开启蓝牙。

2、蓝牙开关控制 BluetoothAdapter.java

package\modules\Bluetooth\framework\java\android\bluetooth\BluetoothAdapter.java

public final class BluetoothAdapter {
    private static final String TAG = "BluetoothAdapter";
    private static final String DESCRIPTOR = "android.bluetooth.BluetoothAdapter";
    private static final boolean DBG = true;
    private static final boolean VDBG = false;

    private final IBluetoothManager mManagerService;
    private IBluetooth mService;

    //1、获取 BluetoothAdapter 的暴露的静态方法
    @RequiresNoPermission
    public static synchronized BluetoothAdapter getDefaultAdapter() {
        if (sAdapter == null) {
            sAdapter = createAdapter(AttributionSource.myAttributionSource());
        }
        return sAdapter;
    }

    //2、打开蓝牙的暴露方法
    @RequiresLegacyBluetoothAdminPermission
    @RequiresBluetoothConnectPermission
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    public boolean enable() {
        if (isEnabled()) {
            if (DBG) {
                Log.d(TAG, "enable(): BT already enabled!");
            }
            return true;
        }
        try {
            return mManagerService.enable(mAttributionSource);
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        }
        return false;
    }

    。。。
}

mAttributionSource 没啥东西,就是应用的基本特征对象,
比如包含了创建类的应用包名和应用的pid和uid,用来区别调用者。

上面开关蓝牙都是通过接口类 IBluetoothManager 实现的。

3、IBluetoothManager 中暴露的实现方法如下:

没啥必要细看,看一遍知道有下面这些方法就行了。

package\modules\Bluetooth\system\binder\android\bluetooth\IBluetoothManager.aidl

interface IBluetoothManager
{
    
    IBluetooth registerAdapter(in IBluetoothManagerCallback callback);
    void unregisterAdapter(in IBluetoothManagerCallback callback);
    void registerStateChangeCallback(in IBluetoothStateChangeCallback callback);
    void unregisterStateChangeCallback(in IBluetoothStateChangeCallback callback);
    boolean enable(in AttributionSource attributionSource);
    boolean enableNoAutoConnect(in AttributionSource attributionSource);
    boolean disable(in AttributionSource attributionSource, boolean persist);
    int getState();
    IBluetoothGatt getBluetoothGatt();
    boolean bindBluetoothProfileService(int profile, String serviceName, IBluetoothProfileServiceConnection proxy);
    void unbindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
    String getAddress(in AttributionSource attributionSource);
    String getName(in AttributionSource attributionSource);
    boolean onFactoryReset(in AttributionSource attributionSource);
    boolean isBleScanAlwaysAvailable();
    boolean enableBle(in AttributionSource attributionSource, IBinder b);
    boolean disableBle(in AttributionSource attributionSource, IBinder b);
    boolean isBleAppPresent();
    boolean isHearingAidProfileSupported();
    int setBtHciSnoopLogMode(int mode);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
    int getBtHciSnoopLogMode();
}

打开和关闭功能是常用的,其他功能不常用;
还有些蓝牙连接之类的功能是其他类控制的。

BluetoothManagerService 是 IBluetoothManager 的实现类。
这类起到比较关键的中间类的作用,打开蓝牙后,
会一直在这里类里面判断蓝牙是否完成打开,并且还有相关日志。

3、蓝牙 IBluetoothManager.java 实现类 BluetoothManagerService

package\modules\Bluetooth\service\src\com\android\server\bluetooth\BluetoothManagerService.java

public class BluetoothManagerService extends IBluetoothManager.Stub {
    private static final String TAG = "BluetoothManagerService";
    private static final boolean DBG = true; //1、可以打开debug模式默认的打开的。

    private IBluetooth mBluetooth;//这个不是底层的,还是上层的接口类
    
    BluetoothManagerService(Context context) {
    //基础设置,广播监听等
    }

    //初始化
    public void handleOnBootPhase() {
        if (DBG) {
            Log.d(TAG, "Bluetooth boot completed");
        }
    }
    
    //2、获取蓝牙是否打开
    public boolean isEnabled() {
        return getState() == BluetoothAdapter.STATE_ON;
    }

    //3、打开蓝牙
    public boolean enable(AttributionSource attributionSource) throws RemoteException {
        final String packageName = attributionSource.getPackageName(); //包名
        //权限检测
        if (!checkBluetoothPermissions(attributionSource, "enable", true)) {
            if (DBG) {
                Log.d(TAG, "enable(): not enabling - bluetooth disallowed");
            }
            return false;
        }
        
        //pid、uid
        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();

        if (isSatelliteModeOn()) {
            Log.d(TAG, "enable(): not enabling - satellite mode is on.");
            return false;
        }

        //4、关键打印,只要打开蓝牙就会有这个打印!
        //每次打开前,mBluetooth 都是null,mBinding 为false,应该是蓝牙关闭置空了
        if (DBG) {
            Log.d(TAG, "enable(" + packageName + "):  mBluetooth=" + mBluetooth + " mBinding="
                    + mBinding + " mState=" + BluetoothAdapter.nameForState(mState));
        }

        synchronized (mReceiver) {
            mQuietEnableExternal = false;
            mEnableExternal = true;
            if (isAirplaneModeOn()) {//5、飞行模式下的处理
               。。。
            }
            // waive WRITE_SECURE_SETTINGS permission check
            // 6、 重要的是 sendEnableMsg 方法的处理
            sendEnableMsg(false, BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
        }
        if (DBG) {
            Log.d(TAG, "enable returning");
        }
        return true;
    }

    // 7、 蓝牙关闭
    public boolean disable(AttributionSource attributionSource, boolean persist)
            throws RemoteException {
        
        //关键打印,只要关闭蓝牙就会有这个打印!
        if (DBG) {
            Log.d(TAG, "disable(): mBluetooth=" + mBluetooth + ", persist=" + persist
                    + ", mBinding=" + mBinding);
        }
    }

...

    // 8、 sendEnableMsg 方法追踪
    private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
        //最后一个参数是否ble,默认都是非ble
        sendEnableMsg(quietMode, reason, packageName, false);
    }

    // 9、 sendEnableMsg 方法追踪
    private void sendEnableMsg(boolean quietMode, int reason, String packageName, boolean isBle) {
        //10、发送Handler消息
        mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0,
                  isBle ? 1 : 0));
        addActiveLog(reason, packageName, true); //日志
        mLastEnabledTime = SystemClock.elapsedRealtime(); //记录时间
    }

    @VisibleForTesting
    class BluetoothHandler extends Handler {
        boolean mGetNameAddressOnly = false;
        private int mWaitForEnableRetry; //打开蓝牙后会多次判断蓝牙是否完成打开
        private int mWaitForDisableRetry;

        BluetoothHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
        case MESSAGE_ENABLE:
                    int quietEnable = msg.arg1;
                    int isBle  = msg.arg2;
 
                    // 10、 第一次不会进入这里,但是后续会持续在这个判断流程,知道蓝牙打开完成或者打开超时(3秒)
                     if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
                            || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
                        // We are handling enable or disable right now, wait for it.
                        mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ENABLE,
                                quietEnable, isBle), ENABLE_DISABLE_DELAY_MS);
                        break;
                    }
 
                    // 12、 打开处理日志
                    if (DBG) {
                        Log.d(TAG, "MESSAGE_ENABLE(" + quietEnable + "): mBluetooth ="
                                + mBluetooth);
                    }
                    
                    mEnable = true;

                    if (isBle == 0) { // 13、非ble会记录蓝牙开关状态
                        persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
                    }

                    // Use service interface to get the exact state
                    mBluetoothLock.readLock().lock();
                    try {//第一次是不会进入这里的
                        if (mBluetooth != null) {
                            boolean isHandled = true;
                            //11、从蓝牙协议状态判断是否ble蓝牙正常打开
                            int state = synchronousGetState();
                            switch (state) {
                                case BluetoothAdapter.STATE_BLE_ON:
                                    if (isBle == 1) {
                                        Log.i(TAG, "Already at BLE_ON State");
                                    } else {
                                        Log.w(TAG, "BT Enable in BLE_ON State, going to ON");
                                        synchronousOnLeServiceUp(mContext.getAttributionSource());
                                    }
                                    break;
                                case BluetoothAdapter.STATE_BLE_TURNING_ON:
                                case BluetoothAdapter.STATE_TURNING_ON:
                                case BluetoothAdapter.STATE_ON:
                                    Log.i(TAG, "MESSAGE_ENABLE: already enabled");
                                    break;
                                default:
                                    isHandled = false;
                                    break;
                            }
                            if (isHandled) break;
                        }
                    } catch (RemoteException | TimeoutException e) {
                        Log.e(TAG, "", e);
                    } finally {
                        mBluetoothLock.readLock().unlock();
                    }

                    //上面只是ble蓝牙的判断,下面的才是重要的判断逻辑。

                    mQuietEnable = (quietEnable == 1);
                    if (mBluetooth == null) { //12、null的情况,进行绑定 IBluetooth
                    //从日志看点击蓝牙开关,第一次到时打印 mBluetooth null
                    //所以  handleEnable才是关键
                        handleEnable(mQuietEnable);
                    } else {
 
                        mWaitForEnableRetry = 0;
                        Message enableDelayedMsg =
                                mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
                       //13、第二次正常是走到这里,发消息后面一直循环判断,知道蓝牙完成打开
                      mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
                    }
                    break;
        case MESSAGE_DISABLE:// 蓝牙关闭
        
        //14、执行打开蓝牙后是走到这里,延时300毫秒继续监听启动蓝牙状况
        case MESSAGE_HANDLE_ENABLE_DELAYED: {
                    // The Bluetooth is turning off, wait for STATE_OFF
                    if (mState != BluetoothAdapter.STATE_OFF) {
                        if (mWaitForEnableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
                            mWaitForEnableRetry++;
                            Message enableDelayedMsg =
                                    mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
                            mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
                            break;
                        } else {
                            Log.e(TAG, "Wait for STATE_OFF timeout");
                        }
                    }
                    // Either state is changed to STATE_OFF or reaches the maximum retry, we
                    // should move forward to the next step.
                    mWaitForEnableRetry = 0;
                    Message restartMsg =
                            mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                    mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
                    Log.d(TAG, "Handle enable is finished");
                    break;
                }
            
        }
    }
    
    //15、打开的关键方法
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    private void handleEnable(boolean quietMode) {
        mQuietEnable = quietMode;

        mBluetoothLock.writeLock().lock();
        try {
            //16、打开蓝牙第一次都会进入这里!
            if ((mBluetooth == null) && (!mBinding)) {
                Log.d(TAG, "binding Bluetooth service");
                //Start bind timeout and bind
                //添加一个绑定超时消息
                Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
                mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
                Intent i = new Intent(IBluetooth.class.getName());
                //17、doBind 方法才是绑定服务,启动蓝牙的关键
                //这个 doBind 方法贼隐蔽,很难看出是关键方法
                if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                        UserHandle.CURRENT)) {
                    mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
                } else {
                    mBinding = true; //正常是进入这里
                }
            } else if (mBluetooth != null) {
                //Enable bluetooth
                try {
                    if (!synchronousEnable(mQuietEnable, mContext.getAttributionSource())) {
                        Log.e(TAG, "IBluetooth.enable() returned false");
                    }
                } catch (RemoteException | TimeoutException e) {
                    Log.e(TAG, "Unable to call enable()", e);
                }
            }
        } finally {
            mBluetoothLock.writeLock().unlock();
        }
    }

     //18、doBind 方法
    boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
        ComponentName comp = resolveSystemService(intent, mContext.getPackageManager(), 0);
        intent.setComponent(comp);
        //19、这里其实就是 bindService,绑定一个具体的service
        //这里类里面是有监听绑定是否成功或者失败监听的
        if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
            Log.e(TAG, "Fail to bind to: " + intent);
            return false;
        }
        return true;
    }

    //20、执行bindService ,成功的情况,这里会有绑定监听回调
    private class BluetoothServiceConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            String name = componentName.getClassName();
            if (DBG) {
                Log.d(TAG, "BluetoothServiceConnection: " + name);
            }
            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
            if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
                msg.arg1 = SERVICE_IBLUETOOTH;
            } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
                msg.arg1 = SERVICE_IBLUETOOTHGATT;
            } else {
                Log.e(TAG, "Unknown service connected: " + name);
                return;
            }
            msg.obj = service;
            mHandler.sendMessage(msg);
        }
    }
    ...//后续流程就不一一分析了。

}

从上面的代码看,debug模式的默认打开的,
最重要的一点是可以看到 打开和关闭蓝牙的日志,
logcat 日志过滤关键字 "BluetoothManagerService"就可以看到是哪个应用在哪个时间点打开、关闭过蓝牙。

并且蓝牙打开成功、失败,绑定蓝牙失败,绑定蓝牙服务超时都是有日志的。

这里的蓝牙服务并不是底层的IBluetooth,而是上层的一个四大组件的Service服务类。
上面调用

4、蓝牙 AdapterService

package\modules\Bluetooth\android\app\src\com\android\bluetooth\btservice\AdapterService.java


public class AdapterService extends Service {  //1、真正的后台服务
    //这个类没啥打印,
    private static final String TAG = "BluetoothAdapterService";
    private static final boolean DBG = true;
    private static final boolean VERBOSE = false;

    private BluetoothAdapter mAdapter;
    @VisibleForTesting
    AdapterProperties mAdapterProperties;
    private AdapterState mAdapterStateMachine;
    private BondStateMachine mBondStateMachine;
    private JniCallbacks mJniCallbacks;
    private RemoteDevices mRemoteDevices;

    public void onCreate() {
        super.onCreate();
        initMetricsLogger();
        debugLog("onCreate()"); //这个是有打印的!只有开机第一次绑定,后续再被绑定不会继续打印
        mDeviceConfigListener.start();
        mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper());
        mRemoteDevices.init();
        clearDiscoveringPackages();
        mBinder = new AdapterServiceBinder(this);
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mAdapterProperties = new AdapterProperties(this);
        。。。
    }


    //2、绑定 IBluetooth 的服务类,调用的方法,是调用到下面方法
    //然后再调用到具体的处理方法
    @VisibleForTesting
    public static class AdapterServiceBinder extends IBluetooth.Stub {
        private AdapterService mService; //通过这个调用到本类实现

        AdapterServiceBinder(AdapterService svc) {
            mService = svc;
            mService.invalidateBluetoothGetStateCache();
            BluetoothAdapter.getDefaultAdapter().disableBluetoothGetStateCache();
        }

        public void cleanup() {
            mService = null;
        }

        public AdapterService getService() {
            if (mService != null && mService.isAvailable()) {
                return mService;
            }
            return null;
        }

        @Override
        public void getState(SynchronousResultReceiver receiver) {
            try {
                receiver.send(getState());
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }
        private int getState() {
            // don't check caller, may be called from system UI
            AdapterService service = getService();
            if (service == null) {
                return BluetoothAdapter.STATE_OFF;
            }

            return service.getState();
        }

        //3、封装的 enable方法,蓝牙开启
        @Override
        public void enable(boolean quietMode, AttributionSource source,
                SynchronousResultReceiver receiver) {
            try {
                receiver.send(enable(quietMode, source));
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }

        //4、继续跟踪 enable方法,蓝牙开启
        private boolean enable(boolean quietMode, AttributionSource attributionSource) {
            AdapterService service = getService();
            if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "enable")
                    || !Utils.checkConnectPermissionForDataDelivery(
                            service, attributionSource, "AdapterService enable")) {
                return false;
            }
            //5、继续跟踪 enable方法,service 的类
            return service.enable(quietMode);
        }

        //关闭蓝牙,就不重复说明了
        @Override
        public void disable(AttributionSource source, SynchronousResultReceiver receiver) {
            try {
                receiver.send(disable(source));
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }
 
        private boolean disable(AttributionSource attributionSource) {
            AdapterService service = getService();
            。。。
            return service.disable();
        }
    
        。。。//service其他暴露的方法,也是差不多的逻辑流程
    }

    //6、service 的开启蓝牙实现方法 enable
    public synchronized boolean enable(boolean quietMode) {
        //这个也会有打印
        debugLog("enable() - Enable called with quiet mode status =  " + quietMode);
        mQuietmode = quietMode;
        //7、AdapterState 状态机执行开启蓝牙
        mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
        return true;
    }

    //8、AdapterState 状态机的逻辑一两句话无法说清楚
    // AdapterState 的处理还涉及 另外一个Service ProfileService,也是四大组件中的Service类

    /**
     * Notify AdapterService that a ProfileService has started or stopped.
     *
     * @param profile the service being removed.
     * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF}
     */
    //9、从上面注释可以看出 ProfileService 启动会 Notify AdapterService
    //但是实际上 ProfileService 是AdapterState状态机 刚开始起来的
    //ProfileService 调用到了AdapterService.startProfileServices()
    //然后就执行到了 onProfileServiceStateChanged,兜兜转转一圈!!!
    public void onProfileServiceStateChanged(ProfileService profile, int state) {
        if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
            throw new IllegalArgumentException(BluetoothAdapter.nameForState(state));
        }
        Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
        m.obj = profile;
        m.arg1 = state;
        mHandler.sendMessage(m);
    }

    //一个Handler消息处理类
    class AdapterServiceHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            verboseLog("handleMessage() - Message: " + msg.what);

            switch (msg.what) {
                case MESSAGE_PROFILE_SERVICE_STATE_CHANGED:
                    verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
                   // 10、 processProfileServiceStateChanged 开启蓝牙 processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1);
                    break;
            
                ...
            }
        }
    
        //11、继续追踪processProfileServiceStateChanged 方法
        private void processProfileServiceStateChanged(ProfileService profile, int state) {
            switch (state) {
                case BluetoothAdapter.STATE_ON:
               
                    if (GattService.class.getSimpleName().equals(profile.getName())) {
                        //11、正常情况打开蓝牙,追踪是调用到 enableNative 方法!
                        enableNative();
                    } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
                            && mRegisteredProfiles.size() == mRunningProfiles.size()) {
                        ...
                    }
                    break;
                case BluetoothAdapter.STATE_OFF:
                ...
            }
        }
        ...
    }

    //12、下面还有一堆native 方法,到这里就终于追到了最接近底层的代码
    /*package*/
    native boolean enableNative();

    /*package*/
    native boolean disableNative();

}

AdapterService 里面的处理逻辑真的会追晕一堆人,简单看一眼看不清楚的逻辑的,跟着日志一边看会好很多。

还有个 AdapterProperties.java 是帮忙处理一些逻辑的。

5、AdapterProperties 是 AdapterService的小助手

这里只简单说一个setName的示例。

比如AdapterService的setName 方法:

        //1、启动类通过Service调用到这里 setName
        @Override
        public void setName(String name, AttributionSource source,
                SynchronousResultReceiver receiver) {
            try {
                receiver.send(setName(name, source));
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }

        //2、继续追踪 setName 方法
        private boolean setName(String name, AttributionSource attributionSource) {
            AdapterService service = getService();
            if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setName")
                    || !Utils.checkConnectPermissionForDataDelivery(
                            service, attributionSource, "AdapterService setName")) {
                return false;
            }
            
            //3、调用到 AdapterProperties对象的 setName 方法
            return service.mAdapterProperties.setName(name);
        }

AdapterProperties.java
class AdapterProperties {
    private static final boolean DBG = true;
    private static final boolean VDBG = false;
    private static final String TAG = "AdapterProperties";

    private AdapterService mService;

     //4、AdapterService onCreate 的时候调用的
    AdapterProperties(AdapterService service) {
        mService = service;
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mScanModeChanges = EvictingQueue.create(SCAN_MODE_CHANGES_MAX_SIZE);
        invalidateBluetoothCaches();
    }
    
    //5、setName方法,AdapterService 调用过来的
    boolean setName(String name) {
        synchronized (mObject) {
            //6、但是最后还是调用回 AdapterService 的 setAdapterPropertyNative,添加了一个参数
            return mService.setAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME,
                    name.getBytes());
        }
    }

}

AdapterService中的方法并不是所有的处理方法都经过 AdapterProperties,只是一部分方法会让 AdapterProperties 进行一些判断和处理。
AdapterProperties.java 代码不多啊,但是也有一千多行。

package\modules\Bluetooth\android\app\jni\com_android_bluetooth_btservice_AdapterService.cpp

代码太多了,这里只抽取蓝牙开启和设置蓝牙名称的方法实现:

//蓝牙开启
static jboolean enableNative(JNIEnv* env, jobject obj) {
  ALOGV("%s", __func__);

  if (!sBluetoothInterface) return JNI_FALSE;
  int ret = sBluetoothInterface->enable();
  return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
                                                             : JNI_FALSE;
}

//设置蓝牙名称
static jboolean setAdapterPropertyNative(JNIEnv* env, jobject obj, jint type,
                                         jbyteArray value) {
  ALOGV("%s", __func__);

  if (!sBluetoothInterface) return JNI_FALSE;

  jbyte* val = env->GetByteArrayElements(value, NULL);
  bt_property_t prop;
  prop.type = (bt_property_type_t)type;
  prop.len = env->GetArrayLength(value);
  prop.val = val;

  int ret = sBluetoothInterface->set_adapter_property(&prop);
  env->ReleaseByteArrayElements(value, val, 0);

  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

看logcat日志是没有这两个方法名称的,不清楚具体原因!
流程肯定是走到了这里的!后续的流程就不继续跟踪了。

三、其他

1、蓝牙开启流程小结

1、应用端 --> BluetoothAdapter.enable();
2、BluetoothAdapter.java --> mManagerService.enable(mAttributionSource);
3、BluetoothManagerService.java -->  doBind AdapterService
4、AdapterService.java --> enableNative();
5、com_android_bluetooth_btservice_AdapterService.cpp 执行对应的native方法

其中比较多处理逻辑的就是 BluetoothManagerService.java 和 AdapterService.java,并且这两个类都是有很多过程打印的。
AdapterService 是一个具体的Service, 还会拉起另外一个服务 ProfileService;
AdapterService 还加载了一个状态机AdapterState 处理一下状态事务;
ProfileService 就是状态机在蓝牙开启的时候拉起的服务;
AdapterService 还声明了 AdapterProperties 相当于工具类,协助处理一些方法的具体判断。

虽然蓝牙相关的几个类关联都比较复杂,但是通过上面的梳理,已经明确很多了。

2、Android 13 蓝牙源码分析

其他人写的,也可以参考一下:
只写了蓝牙相关几个类的作用,没啥具体代码和代码路径。
https://blog.csdn.net/u010870679/article/details/140504014

3、Android14 蓝牙 BluetoothService 启动和相关代码介绍

这个介绍比较简单一点,没有到后面 AdapterService 的代码。
但是对于系统启动后上层是否启动蓝牙有一些分析。

https://blog.csdn.net/wenzhi20102321/article/details/142264944

标签:AdapterService,enable,流程,BluetoothAdapter,蓝牙,private,Android14,boolean
From: https://blog.csdn.net/wenzhi20102321/article/details/142422355

相关文章

  • uniapp - 实现安卓App打包上架应用商店详细教程,详解Hbuilder打包编译apk发布上传到应
    前言【苹果App】打包上架Appstore应用商店,请访问。在uni-app安卓App项目开发中,详解打包app及上架应用市场教程,uniapp打包app安卓应用并发布到软件商店,提供多种方式打包编译为APK文件(HbuilderX云打包/本地原生打包/离线打包),附带申请Android签名证书多种方法、对要上......
  • 告别Win10错误提示:Win10系统igx.dll文件下载、验证与安装全流程解析
    在Windows10系统中,如果遇到因缺少或损坏igx.dll文件而导致的错误提示,您可以通过以下步骤来下载、验证并安装该文件,以恢复系统的正常运行。一、下载igx.dll文件选择可靠的下载源:强烈建议从官方网站、知名软件下载站或受信任的技术论坛下载igx.dll文件。避免从不明来源下......
  • 【产品经理修炼之道】- 怎么搭建OA系统:审批流程
    在OA系统中,大部分功能都会有审批流程。会围绕“人、事、物、财”产生变更。本文作者总结了审批流程的处理和经验,供大家参考。一、为什么要有审批流程企业系统管理中大部分的功能模块都会和审批流关联,一个便捷高效的审批流管理方案,能极大减少沟通协同的成本,提高企业内协作的......
  • WINDOWS安装RAGFLOW完整流程
    RAGFLOW是比较强大的知识库,支持搜索,聊天多种模式。知识库相比anyllm,fastgpt,dify,maxkb更强大,支持自定义分隔符,支持各种大模型提供商,如ollama等。官方体验地址,RAGFlow1:虚拟机安装:不建议通过wsl安装,wsl会遇到systecmctl不可用等诸多问题。以VMWarePro为例,参考下面链接完成安装......
  • 低代码平台:流程设计的革新
    在数字化时代,软件开发的需求日益增长,但传统的编码方式往往耗时且需要专业技能。为了解决这一问题,勤研低代码开发平台做出了许多努力,它允许开发者通过直观的节点属性设置来设计复杂的业务流程,大大降低了开发的门槛和时间成本。流程可视化低代码开发平台的核心在于其“可视化”......
  • 中移ML307开发板板载蓝牙使用教程-下载和运行第一个程序
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ML307_OPEN_BLE"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  开发单片机准备工作一,安装......
  • Java流程控制语句——条件控制语句详解(附有流程图)
    在Java编程中,条件控制语句用于控制程序的执行路径,决定根据某些条件来选择执行某段代码或跳过某段代码。它们是Java编程的重要组成部分,帮助开发者根据不同的输入、状态或数据流来编写更加灵活和动态的代码。在本文中,我们将详细讲解Java中的几种条件控制语句:if-else、else......
  • 挖矿病毒处理流程(门罗币)
    1.检查自启动项执行systemctllist-unit-files--type=service|grepenabled命令列出全部自启动项,有异常启动项执行systemctldisableA_li_yun_Duns.service删除。A_li_yun_Duns.service为自启动项名称。2.检查系统用户执行vi/etc/passwd检查系统用户,如有异常用户将其禁用,......
  • Spring的启动流程
    Spring容器的启动流程是一个复杂的过程,涉及多个阶段和组件的协作。核心是ApplicationContext(如ClassPathXmlApplicationContext、AnnotationConfigApplicationContext等)接口的启动。通过对Spring启动流程的详细分析,可以更好地理解Spring是如何加载、解析、实例化、初始化并管理Bea......
  • oracle常用后台进程及sql语句执行流程
    1.checkpoint功能:减少崩溃恢复crashrecovery时间。检查点可以确保在某个时间点之前的所有事务都写入磁盘,保证数据一致性后台进程ckpt触发,ckpt通知dbwr进程将脏数据库dirtybuffer写出到数据文件上.更新数据文件头及控制文件上的检查点触发条件:数据库一致性关闭、altersystem......