Android Bluetooth启动

一、启动概述

从按下Android设备的电源键,启动顺序大致如下:

  1. Bootloader引导,加载、启动Kernel;
  2. 创建init进程,在不同启动阶段做不同的事;
  3. 创建Zygote进程;
  4. 创建SystemServer;

从Android 8开始,google引入了Treble后,相关的架构都基本上是Framework和vendor hal通过hidl service通信。从Android 11开始,google又引入了适用于HAL的AIDL,不过蓝牙还是用的hidl。

二、蓝牙HIDL Service启动

可以先找一台手机,执行下面命令看一下:

adb shell ps -u bluetooth

 能看到有三个共享bluetooth uid的进程。

第一个pid为1185的进程是启动的hidl service。

在rc文件中,定义如下:

service vendor.bluetooth-1-0-qti /vendor/bin/hw/[email protected]
    class hal
    user bluetooth
    group bluetooth system wakelock oem_2901 net_raw
    capabilities BLOCK_SUSPEND NET_ADMIN

该Service "vendor.bluetooth-1-0-qti"不是通过start命令启动的,而是通过class_start的方式启动。其class为hal,定义在init.rc文件中的启动阶段如下:

on boot
    # Start standard binderized HAL daemons
    class_start hal

因此,"vendor.bluetooth-1-0-qti"在boot阶段启动了。

init启动顺序可以参考Android系统启动-Init篇 - Gityuan博客 | 袁辉辉的技术博客。

三、BluetoothManagerService启动

在late-init阶段,会触发zygote-start,zygote的启动就参考Android系统启动-zygote篇 - Gityuan博客 | 袁辉辉的技术博客,然后zygote fork出SystemServer,参考Android系统启动-SystemServer上篇 - Gityuan博客 | 袁辉辉的技术博客,

# Mount filesystems and start core system services.
on late-init

    # Now we can start zygote for devices with file based encryption
    trigger zygote-start

    trigger early-boot
    trigger boot

# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted
    wait_for_prop odsign.verification.done 1
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start statsd
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=unsupported
    wait_for_prop odsign.verification.done 1
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start statsd
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
    wait_for_prop odsign.verification.done 1
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start statsd
    start netd
    start zygote
    start zygote_secondary

SystemServer启动后,在startOtherService阶段,启动BluetoothManagerService(后面简称BMS)

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
     */
    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        t.traceBegin("startOtherServices");
// ......
            if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                Slog.i(TAG, "No Bluetooth Service (factory test)");
            } else if (!context.getPackageManager().hasSystemFeature
                    (PackageManager.FEATURE_BLUETOOTH)) {
                Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");
            } else {
                t.traceBegin("StartBluetoothService");
                mSystemServiceManager.startService(BluetoothService.class);
                t.traceEnd();
            }
// ......
        t.traceEnd(); // startOtherServices
    }

到SystemServiceManager.java中调用:

    /**
     * Starts a service by class name.
     *
     * @return The service instance.
     */
    public SystemService startService(String className) {
        final Class serviceClass = loadClassFromLoader(className,
                this.getClass().getClassLoader());
        return startService(serviceClass);
    }

    /*
     * Loads and initializes a class from the given classLoader. Returns the class.
     */
    @SuppressWarnings("unchecked")
    private static Class loadClassFromLoader(String className,
            ClassLoader classLoader) {
        try {
            return (Class) Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("Failed to create service " + className
                    + " from class loader " + classLoader.toString() + ": service class not "
                    + "found, usually indicates that the caller should "
                    + "have called PackageManager.hasSystemFeature() to check whether the "
                    + "feature is available on this device before trying to start the "
                    + "services that implement it. Also ensure that the correct path for the "
                    + "classloader is supplied, if applicable.", ex);
        }
    }


    /**
     * Creates and starts a system service. The class must be a subclass of
     * {@link com.android.server.SystemService}.
     *
     * @param serviceClass A Java class that implements the SystemService interface.
     * @return The service instance, never null.
     * @throws RuntimeException if the service fails to start.
     */
    public  T startService(Class serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                Constructor constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }

            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

然后就分别调用BluetoothService.java的构造方法以及onStart()方法。

class BluetoothService extends SystemService {
    private BluetoothManagerService mBluetoothManagerService;
    private boolean mInitialized = false;

    public BluetoothService(Context context) {
        super(context);
        mBluetoothManagerService = new BluetoothManagerService(context);
    }
// ......
}

在BluetoothService的构造函数中,创建了BMS的对象。

Android这块依旧采用CS架构,即通过BluetoothAdapter持有IBluetoothManager,作为BMS的代理。

    /**
     * Get a handle to the default local Bluetooth adapter.
     * 

* Currently Android only supports one Bluetooth adapter, but the API could * be extended to support more. This will always return the default adapter. *

* * @return the default local adapter, or null if Bluetooth is not supported * on this hardware platform * @deprecated this method will continue to work, but developers are * strongly encouraged to migrate to using * {@link BluetoothManager#getAdapter()}, since that approach * enables support for {@link Context#createAttributionContext}. */ @Deprecated @RequiresNoPermission public static synchronized BluetoothAdapter getDefaultAdapter() { if (sAdapter == null) { sAdapter = createAdapter(BluetoothManager.resolveAttributionSource(null)); } return sAdapter; } /** {@hide} */ public static BluetoothAdapter createAdapter(AttributionSource attributionSource) { IBinder binder = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE); if (binder != null) { return new BluetoothAdapter(IBluetoothManager.Stub.asInterface(binder), attributionSource); } else { Log.e(TAG, "Bluetooth binder is null"); return null; } }
class BluetoothManagerService extends IBluetoothManager.Stub 

然后再来看BMS的构造函数做了哪些工作,代码就


    BluetoothManagerService(Context context) {
        // 一些全局变量的初始化工作
        mHandler = new BluetoothHandler(IoThread.get().getLooper());

        mContext = context;

        mWirelessConsentRequired = context.getResources()
                .getBoolean(com.android.internal.R.bool.config_wirelessConsentRequired);

        mCrashes = 0;
        // IBluetooth的引用,其Server端在AdapterService$AdapterServiceBinder
        mBluetooth = null;
        mBluetoothBinder = null;
        // IBluetoothGatt的引用,其Server端在GattService$BluetoothGattBinder
        mBluetoothGatt = null;
        mBinding = false;
        mTryBindOnBindTimeout = false;
        mUnbinding = false;
        mEnable = false;
        mState = BluetoothAdapter.STATE_OFF;
        mQuietEnableExternal = false;
        mEnableExternal = false;
        mAddress = null;
        mName = null;
        mErrorRecoveryRetryCounter = 0;
        mContentResolver = context.getContentResolver();
        mUserId = mContentResolver.getUserId();
        // Observe BLE scan only mode settings change.
        // 这里注册对于蓝牙扫描开关变化的观测,这个开关位于定位开关的分类下面。
        // 具体在packages/apps/Settings/src/com/android/settings/location/下
        registerForBleScanModeChange();
        // 用于通知bluetoothService的连接状态,BREDR关闭
        mCallbacks = new RemoteCallbackList();
        // 用于通知蓝牙开关状态
        mStateChangeCallbacks = new RemoteCallbackList();
        // 是否支持助听器
        mIsHearingAidProfileSupported = context.getResources()
                .getBoolean(com.android.internal.R.bool.config_hearing_aid_profile_supported);

        // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
        // 读persist.sys.fflag.override.settings_bluetooth_hearing_aid属性值
        String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
        if (!TextUtils.isEmpty(value)) {
            boolean isHearingAidEnabled = Boolean.parseBoolean(value);
            Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
            FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
            if (isHearingAidEnabled && !mIsHearingAidProfileSupported) {
                // Overwrite to enable support by FeatureFlag
                mIsHearingAidProfileSupported = true;
            }
        }
        // 注册动态广播接收器
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
        filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
        filter.addAction(Intent.ACTION_SETTING_RESTORED);
        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
        filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        mContext.registerReceiver(mReceiver, filter);
        // 加载本机蓝牙名称和地址
        loadStoredNameAndAddress();
        // 读取上一次手机的蓝牙开关值
        if (isBluetoothPersistedStateOn()) {
            if (DBG) {
                Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
            }
            mEnableExternal = true;
        }
        // 读取打开飞行模式下,需要关闭的射频信号列表
        // adb shell settings get global airplane_mode_radios
        // 我的设备返回cell,bluetooth,wifi,nfc,wimax
        String airplaneModeRadios =
                Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
        if (airplaneModeRadios == null || airplaneModeRadios.contains(
                Settings.Global.RADIO_BLUETOOTH)) {
            mBluetoothAirplaneModeListener = new BluetoothAirplaneModeListener(
                    this, IoThread.get().getLooper(), context);
        }

        // 获取SystemUI的uid
        int systemUiUid = -1;
        // Check if device is configured with no home screen, which implies no SystemUI.
        boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
        if (!noHome) {
            PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
            systemUiUid = pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(),
                    MATCH_SYSTEM_ONLY, USER_SYSTEM);
        }
        if (systemUiUid >= 0) {
            Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
        } else {
            // Some platforms, such as wearables do not have a system ui.
            Slog.w(TAG, "Unable to resolve SystemUI's UID.");
        }
        mSystemUiUid = systemUiUid;
    }

System Service的启动阶段大概有下面几个,然后onBootPhase在boot的不同阶段都会被调用到,按数字从小到大的顺序递进。

    /**
     * The earliest boot phase the system send to system services on boot.
     */
    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;

    /**
     * Boot phase that blocks on SensorService availability. The service gets started
     * asynchronously since it may take awhile to actually finish initializing.
     *
     * @hide
     */
    public static final int PHASE_WAIT_FOR_SENSOR_SERVICE = 200;

    /**
     * After receiving this boot phase, services can obtain lock settings data.
     */
    public static final int PHASE_LOCK_SETTINGS_READY = 480;

    /**
     * After receiving this boot phase, services can safely call into core system services
     * such as the PowerManager or PackageManager.
     */
    public static final int PHASE_SYSTEM_SERVICES_READY = 500;

    /**
     * After receiving this boot phase, services can safely call into device specific services.
     */
    public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

    /**
     * After receiving this boot phase, services can broadcast Intents.
     */
    public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

    /**
     * After receiving this boot phase, services can start/bind to third party apps.
     * Apps will be able to make Binder calls into services at this point.
     */
    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

    /**
     * After receiving this boot phase, services can allow user interaction with the device.
     * This phase occurs when boot has completed and the home application has started.
     * System services may prefer to listen to this phase rather than registering a
     * broadcast receiver for {@link android.content.Intent#ACTION_LOCKED_BOOT_COMPLETED}
     * to reduce overall latency.
     */
    public static final int PHASE_BOOT_COMPLETED = 1000;

当在SystemService.PHASE_SYSTEM_SERVICES_READY时,会将BMS加入到SystemServer,这样其他的进程就可以访问到了。在SystemService.PHASE_ACTIVITY_MANAGER_READY阶段并且非无头模式下,会调用BMS的handleOnBootPhase()方法。

class BluetoothService extends SystemService {
    private BluetoothManagerService mBluetoothManagerService;
    private boolean mInitialized = false;

    public BluetoothService(Context context) {
        super(context);
        mBluetoothManagerService = new BluetoothManagerService(context);
    }

    private void initialize() {
        if (!mInitialized) {
            mBluetoothManagerService.handleOnBootPhase();
            mInitialized = true;
        }
    }

    @Override
    public void onStart() {
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,
                    mBluetoothManagerService);
        } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY &&
                !UserManager.isHeadlessSystemUserMode()) {
            initialize();
        }
    }

    @Override
    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
        if (!mInitialized) {
            initialize();
        } else {
            mBluetoothManagerService.handleOnSwitchUser(to.getUserIdentifier());
        }
    }

    @Override
    public void onUserUnlocking(@NonNull TargetUser user) {
        mBluetoothManagerService.handleOnUnlockUser(user.getUserIdentifier());
    }
}

继续聊到BMS的handleOnBootPhase()方法

    /**
     * Send enable message and set adapter name and address. Called when the boot phase becomes
     * PHASE_SYSTEM_SERVICES_READY.
     */
    public void handleOnBootPhase() {
        if (DBG) {
            Slog.d(TAG, "Bluetooth boot completed");
        }
        // 获取AppOps对象,后续调用相关方法时会有权限检查。
        mAppOps = mContext.getSystemService(AppOpsManager.class);
        UserManagerInternal userManagerInternal =
                LocalServices.getService(UserManagerInternal.class);
        userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
        final boolean isBluetoothDisallowed = isBluetoothDisallowed();
        if (isBluetoothDisallowed) {
            return;
        }
        final boolean isSafeMode = mContext.getPackageManager().isSafeMode();
        if (mEnableExternal && isBluetoothPersistedStateOnBluetooth() && !isSafeMode) {
            if (DBG) {
                Slog.d(TAG, "Auto-enabling Bluetooth.");
            }
            sendEnableMsg(mQuietEnableExternal,
                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
                    mContext.getPackageName());
        } else if (!isNameAndAddressSet()) {
            if (DBG) {
                Slog.d(TAG, "Getting adapter name and address");
            }
            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
            mHandler.sendMessage(getMsg);
        }

        mBluetoothModeChangeHelper = new BluetoothModeChangeHelper(mContext);
        if (mBluetoothAirplaneModeListener != null) {
            mBluetoothAirplaneModeListener.start(mBluetoothModeChangeHelper);
        }
        registerForProvisioningStateChange();
        mBluetoothDeviceConfigListener = new BluetoothDeviceConfigListener(this, DBG);
    }

四、打开蓝牙开关

打开蓝牙开关的动作,会调用到BMS的handleEnable方法。

    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    private void handleEnable(boolean quietMode) {
        mQuietEnable = quietMode;

        try {
            // 加锁
            mBluetoothLock.writeLock().lock();
            // 如果IBluetooth的引用为空并且mBinding为false
            if ((mBluetooth == null) && (!mBinding)) {
                // 在一个timeout期间需要绑定蓝牙服务成功
                Slog.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());
                if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                        UserHandle.CURRENT)) {
                    // bind失败,移除Handler消息
                    mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
                } else {
                    // bind成功
                    mBinding = true;
                    mBindingUserID = ActivityManager.getCurrentUser();
                    Slog.d(TAG, "Binding BT service. Current user: " + mBindingUserID);
                }
            } else if (mBluetooth != null) {
                //Enable bluetooth
                try {
                    // 调用IBluetooth的enable方法
                    if (!mBluetooth.enable(mQuietEnable, mContext.getAttributionSource())) {
                        Slog.e(TAG, "IBluetooth.enable() returned false");
                    }
                } catch (RemoteException e) {
                    Slog.e(TAG, "Unable to call enable()", e);
                }
            }
        } finally {
            // 解锁
            mBluetoothLock.writeLock().unlock();
        }
    }

    boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
        intent.setComponent(comp);
        if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
            Slog.e(TAG, "Fail to bind to: " + intent);
            return false;
        }
        return true;
    }

如果你看的是高通的源码,你会发现packages/apps/Bluetooth和vendor/qcom/opensource/commonsys/packages/apps/Bluetooth这两个仓库的存在,然后Bluetooth apk的name是一样的,都是下面这种:

android_app {
    name: "Bluetooth",

    // ......
}

看下PRODUCT_PACKAGE,使用的是vendor/qcom/opensource/commonsys/packages/apps/Bluetooth仓库。

MTK使用的是packages/apps/Bluetooth仓库。

bind Service,会启动AdapterService

        
            
                
            
        

在其生命周期的开始,走到onCreate方法,里面的初始化动作很多,这里只贴与后面分析的有关的一些动作。

mAdapterStateMachine =  AdapterState.make(this);

    public static AdapterState make(AdapterService service) {
        Log.d(TAG, "make() - Creating AdapterState");
        AdapterState as = new AdapterState(service);
        as.start();
        return as;
    }

然后调用到其父类的start方法,并继续调用completeConstruction(),到这先停一下,这边的分析后面再讲。

    public void start() {
        // mSmHandler can be null if the state machine has quit.
        SmHandler smh = mSmHandler;
        if (smh == null) return;

        /** Send the complete construction message */
        smh.completeConstruction();
    }

继续回到enable方法,mBluetooth.enable(mQuietEnable, mContext.getAttributionSource())这段函数调用就会走到静态内部类AdapterService$AdapterServiceBinder的enable方法。

    private 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 boolean enable(boolean quietMode, AttributionSource attributionSource) {
            AdapterService service = getService();
            if (service == null || !callerIsSystemOrActiveUser(TAG, "enable")
                    || !Utils.checkConnectPermissionForDataDelivery(
                            service, attributionSource, "AdapterService enable")) {
                return false;
            }
            return service.enable();
        }
    }

然后会调用到外部类AdapterService的enable方法

    private AdapterState mAdapterStateMachine;

    public boolean enable() {
        return enable(false);
    }

    public synchronized boolean enable(boolean quietMode) {
        // Enforce the user restriction for disallowing Bluetooth if it was set.
        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) {
            debugLog("enable() called when Bluetooth was disallowed");
            return false;
        }

        debugLog("enable() - Enable called with quiet mode status =  " + quietMode);
        mQuietmode = quietMode;
        // 通过AdapterState实现状态机
        mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
        return true;
    }

下面给出关于AdapterState的描述

/**
 * This state machine handles Bluetooth Adapter State.
 * Stable States:
 *      {@link OffState}: Initial State
 *      {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on
 *      {@link OnState} : Bluetooth is on (All supported profiles)
 *
 * Transition States:
 *      {@link TurningBleOnState} : OffState to BleOnState
 *      {@link TurningBleOffState} : BleOnState to OffState
 *      {@link TurningOnState} : BleOnState to OnState
 *      {@link TurningOffState} : OnState to BleOnState
 *
 *        +------   Off  <-----+
 *        |                    |
 *        v                    |
 * TurningBleOn   TO--->   TurningBleOff
 *        |                  ^ ^
 *        |                  | |
 *        +----->        ----+ |
 *                 BleOn       |
 *        +------        <---+ O
 *        v                  | T
 *    TurningOn  TO---->  TurningOff
 *        |                    ^
 *        |                    |
 *        +----->   On   ------+
 *
 */

这几个状态,包括稳定的状态和迁移的状态,都以类的形式存在,继承自抽象类BaseAdapterState

OnState

BleOnState
OffState

TurningOnState

TurningOffState

TurningBleOnState
TurningBleOffState

再回到mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON)这边的调用,

会走到内部类StateMachine$SmHandler的handleMessage


        /**
         * Handle messages sent to the state machine by calling
         * the current state's processMessage. It also handles
         * the enter/exit calls and placing any deferred messages
         * back onto the queue when transitioning to a new state.
         */
        @Override
        public final void handleMessage(Message msg) {
            if (!mHasQuit) {
                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {
                    mSm.onPreHandleMessage(msg);
                }

                if (mDbg) mSm.log("handleMessage: E msg.what=" + msg.what);

                /** Save the current message */
                mMsg = msg;

                /** State that processed the message */
                State msgProcessedState = null;
                if (mIsConstructionCompleted || (mMsg.what == SM_QUIT_CMD)) {
                    /** Normal path */
                    msgProcessedState = processMsg(msg);
                } else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD)
                        && (mMsg.obj == mSmHandlerObj)) {
                    /** Initial one time path. */
                    mIsConstructionCompleted = true;
                    invokeEnterMethods(0);
                } else {
                    throw new RuntimeException("StateMachine.handleMessage: "
                            + "The start method not called, received msg: " + msg);
                }
                performTransitions(msgProcessedState, msg);

                // We need to check if mSm == null here as we could be quitting.
                if (mDbg && mSm != null) mSm.log("handleMessage: X");

                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {
                    mSm.onPostHandleMessage(msg);
                }
            }
        }

这里面最重要的就是performTransitions方法,他会不停地迁移状态。

        /**
         * Do any transitions
         * @param msgProcessedState is the state that processed the message
         */
        private void performTransitions(State msgProcessedState, Message msg) {
            /**
             * If transitionTo has been called, exit and then enter
             * the appropriate states. We loop on this to allow
             * enter and exit methods to use transitionTo.
             */
            State orgState = mStateStack[mStateStackTopIndex].state;

            /**
             * Record whether message needs to be logged before we transition and
             * and we won't log special messages SM_INIT_CMD or SM_QUIT_CMD which
             * always set msg.obj to the handler.
             */
            boolean recordLogMsg = mSm.recordLogRec(mMsg) && (msg.obj != mSmHandlerObj);

            if (mLogRecords.logOnlyTransitions()) {
                /** Record only if there is a transition */
                if (mDestState != null) {
                    mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
                            orgState, mDestState);
                }
            } else if (recordLogMsg) {
                /** Record message */
                mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState, orgState,
                        mDestState);
            }

            State destState = mDestState;
            if (destState != null) {
                /**
                 * Process the transitions including transitions in the enter/exit methods
                 */
                while (true) {
                    if (mDbg) mSm.log("handleMessage: new destination call exit/enter");

                    /**
                     * Determine the states to exit and enter and return the
                     * common ancestor state of the enter/exit states. Then
                     * invoke the exit methods then the enter methods.
                     */
                    StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);
                    // flag is cleared in invokeEnterMethods before entering the target state
                    mTransitionInProgress = true;
                    invokeExitMethods(commonStateInfo);
                    int stateStackEnteringIndex = moveTempStateStackToStateStack();
                    invokeEnterMethods(stateStackEnteringIndex);

                    /**
                     * Since we have transitioned to a new state we need to have
                     * any deferred messages moved to the front of the message queue
                     * so they will be processed before any other messages in the
                     * message queue.
                     */
                    moveDeferredMessageAtFrontOfQueue();

                    if (destState != mDestState) {
                        // A new mDestState so continue looping
                        destState = mDestState;
                    } else {
                        // No change in mDestState so we're done
                        break;
                    }
                }
                mDestState = null;
            }

            /**
             * After processing all transitions check and
             * see if the last transition was to quit or halt.
             */
            if (destState != null) {
                if (destState == mQuittingState) {
                    /**
                     * Call onQuitting to let subclasses cleanup.
                     */
                    mSm.onQuitting();
                    cleanupAfterQuitting();
                } else if (destState == mHaltingState) {
                    /**
                     * Call onHalting() if we've transitioned to the halting
                     * state. All subsequent messages will be processed in
                     * in the halting state which invokes haltedProcessMessage(msg);
                     */
                    mSm.onHalting();
                }
            }
        }

到这边,虽然看注释是知道怎么状态迁移的,但是看方法实现还是很乱的。

首先,需要先看AdapterState的构造函数,首先调用了父类的构造函数,然后分别将各个的稳定态和迁移态加入HashMap,最后将Off态设置为初始态。其实在SmHandler的构造函数中,会先加入两个状态HaltingState和QuittingState

    private AdapterState(AdapterService service) {
        super(TAG);
        addState(mOnState);
        addState(mBleOnState);
        addState(mOffState);
        addState(mTurningOnState);
        addState(mTurningOffState);
        addState(mTurningBleOnState);
        addState(mTurningBleOffState);
        mAdapterService = service;
        setInitialState(mOffState);
    }
private HashMap mStateInfo = new HashMap();

        /**
         * Add a new state to the state machine. Bottom up addition
         * of states is allowed but the same state may only exist
         * in one hierarchy.
         *
         * @param state the state to add
         * @param parent the parent of state
         * @return stateInfo for this state
         */
        private final StateInfo addState(State state, State parent) {
            if (mDbg) {
                mSm.log("addStateInternal: E state=" + state.getName() + ",parent="
                        + ((parent == null) ? "" : parent.getName()));
            }
            StateInfo parentStateInfo = null;
            if (parent != null) {
                parentStateInfo = mStateInfo.get(parent);
                if (parentStateInfo == null) {
                    // Recursively add our parent as it's not been added yet.
                    parentStateInfo = addState(parent, null);
                }
            }
            StateInfo stateInfo = mStateInfo.get(state);
            if (stateInfo == null) {
                stateInfo = new StateInfo();
                mStateInfo.put(state, stateInfo);
            }

            // Validate that we aren't adding the same state in two different hierarchies.
            if ((stateInfo.parentStateInfo != null)
                    && (stateInfo.parentStateInfo != parentStateInfo)) {
                throw new RuntimeException("state already added");
            }
            stateInfo.state = state;
            stateInfo.parentStateInfo = parentStateInfo;
            stateInfo.active = false;
            if (mDbg) mSm.log("addStateInternal: X stateInfo: " + stateInfo);
            return stateInfo;
        }

        /** @see StateMachine#setInitialState(State) */
        private final void setInitialState(State initialState) {
            if (mDbg) mSm.log("setInitialState: initialState=" + initialState.getName());
            mInitialState = initialState;
        }

    public final void addState(State state) {
        mSmHandler.addState(state, null);
    }

    public final void setInitialState(State initialState) {
        mSmHandler.setInitialState(initialState);
    }
        /**
         * Constructor
         *
         * @param looper for dispatching messages
         * @param sm the hierarchical state machine
         */
        private SmHandler(Looper looper, StateMachine sm) {
            super(looper);
            mSm = sm;

            addState(mHaltingState, null);
            addState(mQuittingState, null);
        }

再回头看状态迁移,最骚的就是这个数组,索引看着是真的头大,所以这个数组的变化得时刻注意。分析的时候,可以自己写一个表格,把索引和数组的内容记下来,你会发现enable过程中,在一次次的状态迁移中,是向这个数组中添加元素;相应地disable过程就是从数组中移除元素的过程。

        /** Stack used to manage the current hierarchy of states */
        private StateInfo mStateStack[];

        /** Top of mStateStack */
        private int mStateStackTopIndex = -1;

        /** A temporary stack used to manage the state stack */
        private StateInfo mTempStateStack[];

        /** The top of the mTempStateStack */
        private int mTempStateStackCount;

前面讲过,在AdapterService的onCreate方法中,会走到StateMachine的completeConstruction方法,

        /**
         * Complete the construction of the state machine.
         */
        private final void completeConstruction() {
            if (mDbg) mSm.log("completeConstruction: E");

            /**
             * Determine the maximum depth of the state hierarchy
             * so we can allocate the state stacks.
             */
            int maxDepth = 0;
            for (StateInfo si : mStateInfo.values()) {
                int depth = 0;
                for (StateInfo i = si; i != null; depth++) {
                    i = i.parentStateInfo;
                }
                if (maxDepth < depth) {
                    maxDepth = depth;
                }
            }
            if (mDbg) mSm.log("completeConstruction: maxDepth=" + maxDepth);

            mStateStack = new StateInfo[maxDepth];
            mTempStateStack = new StateInfo[maxDepth];
            setupInitialStateStack();

            /** Sending SM_INIT_CMD message to invoke enter methods asynchronously */
            sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));

            if (mDbg) mSm.log("completeConstruction: X");
        }

        /**
         * Initialize StateStack to mInitialState.
         */
        private final void setupInitialStateStack() {
            if (mDbg) {
                mSm.log("setupInitialStateStack: E mInitialState=" + mInitialState.getName());
            }

            StateInfo curStateInfo = mStateInfo.get(mInitialState);
            for (mTempStateStackCount = 0; curStateInfo != null; mTempStateStackCount++) {
                mTempStateStack[mTempStateStackCount] = curStateInfo;
                curStateInfo = curStateInfo.parentStateInfo;
            }

            // Empty the StateStack
            mStateStackTopIndex = -1;

            moveTempStateStackToStateStack();
        }

在AdapterState的构造函数中,会将各个稳定态和迁移态加入到mStateInfo这个HashMap中,在completeConstruction中会遍历mStateInfo,然后完成数组mStateStack、mTempStateStack的初始化工作,并发送SM_INIT_CMD的Message。

为了不那么啰嗦,总结下在enable过程中的几个主要方法:

addState:新增状态State

completeConstruction:初始化mStateStack和mTempStateStack

setupInitialStateStack:将初始状态加入到mTempStateStack中

moveTempStateStackToStateStack:将mTempStateStack相应索引值复制到mStateStack,并移动Top索引值

setupTempStateStackWithStatesToEnter:向mTempStateStack新增状态State

processMsg:将位于Top索引的State返回,作为当前的State

transitionTo:设置目标State

invokeEnterMethods:调用入参索引值和Top索引值之间所有的mStateStack对象的enter方法,其实在状态迁移过程中,逻辑上只会走到Top对应State的enter方法

invokeExitMethods:调用Top索引mStateStack对象的exit方法

performTransitions:退出当前State,进入目标State

handleMessage:处理消息,会先调用当前状态的exit方法,然后移动Top索引,将目标状态设置为当前状态,再调用当前状态的enter方法

现在再来总结几个状态的变化:

  • 初始状态为OffState,发送BLE_TURN_ON的消息后,状态迁移到TurningBleOnState;
  • 迁移到TurningBleOnState过程中,先调用其enter方法,发送一个BLE_START_TIMEOUT消息(用于处理打开超时),调用mAdapterService.bringUpBle(),在这里会启动GattService。由于GattService继承自ProfileService,启动后会调用到mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON),并执行enableNative动作。
  • 当ble打开成功后,会有回调stateChangeCallback,若返回的状态为AbstractionLayer.BT_STATE_ON,则发送BLE_STARTED的消息;
  • 收到上述BLE_STARTED消息后,先执行TurningBleOnState状态的exit方法,移除超时消息处理,然后将状态迁移到BleOnState;

再来看BMS中的mBluetoothCallback回调,当Bluetooth state发生变化时,会走进该回调

    private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
        @Override
        public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
            Message msg =
                    mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
            mHandler.sendMessage(msg);
        }
    };

相应message的处理方法为:

                case MESSAGE_BLUETOOTH_STATE_CHANGE: {
                    int prevState = msg.arg1;
                    int newState = msg.arg2;
                    if (DBG) {
                        Slog.d(TAG,
                                "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
                                        prevState) + " > " + BluetoothAdapter.nameForState(
                                        newState));
                    }
                    mState = newState;
                    bluetoothStateChangeHandler(prevState, newState);
                    // handle error state transition case from TURNING_ON to OFF
                    // unbind and rebind bluetooth service and enable bluetooth
                    if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
                            == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
                        recoverBluetoothServiceFromError(false);
                    }
                    if ((prevState == BluetoothAdapter.STATE_TURNING_ON) &&
                            (newState == BluetoothAdapter.STATE_OFF) &&
                            (mBluetooth != null) && mEnable) {
                         persistBluetoothSetting(BLUETOOTH_OFF);
                    }
                    if ((prevState == BluetoothAdapter.STATE_TURNING_ON) &&
                           (newState == BluetoothAdapter.STATE_BLE_ON) &&
                           (mBluetooth != null) && mEnable) {
                        recoverBluetoothServiceFromError(true);
                    }
                    // If we tried to enable BT while BT was in the process of shutting down,
                    // wait for the BT process to fully tear down and then force a restart
                    // here.  This is a bit of a hack (b/29363429).
                    if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
                            == BluetoothAdapter.STATE_OFF)) {
                        if (mEnable) {
                            Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
                            mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                            waitForState(Set.of(BluetoothAdapter.STATE_OFF));
                            Message restartMsg =
                                    mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                            mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
                        }
                    }
                    if (newState == BluetoothAdapter.STATE_ON
                            || newState == BluetoothAdapter.STATE_BLE_ON) {
                        // bluetooth is working, reset the counter
                        if (mErrorRecoveryRetryCounter != 0) {
                            Slog.w(TAG, "bluetooth is recovered from error");
                            mErrorRecoveryRetryCounter = 0;
                        }
                    }
                    break;
                }

会调用到bluetoothStateChangeHandler方法,截取里面几行重要的

接着之前的状态机分析,走到了BleOnState,那么在bluetoothStateChangeHandler方法中,prevState为BLE_TURNING_ON,newState为BLE_ON,则intermediate_off为false,

    private void bluetoothStateChangeHandler(int prevState, int newState) {
// ......
 else if (!intermediate_off) {
                // connect to GattService
                if (DBG) {
                    Slog.d(TAG, "Bluetooth is in LE only mode");
                }
                if (mBluetoothGatt != null || !mContext.getPackageManager()
                            .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
                    continueFromBleOnState();
                } else {
                    if (DBG) {
                        Slog.d(TAG, "Binding Bluetooth GATT service");
                    }
                    Intent i = new Intent(IBluetoothGatt.class.getName());
                    doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                            UserHandle.CURRENT);
                }
                sendBleStateChanged(prevState, newState);
                //Don't broadcase this as std intent
                isStandardBroadcast = false;

            }
// ......
    }

这时候,mBluetoothGatt还为null,就走到了doBind,去启动Gatt Service了

调用continueFromBleOnState()方法,从方法名就可以知道它要做什么了。

    /**
     * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on,
     * call IBluetooth.onBrEdrDown() to disable if Bluetooth should be off.
     */
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
    private void continueFromBleOnState() {
        if (DBG) {
            Slog.d(TAG, "continueFromBleOnState()");
        }
        try {
            mBluetoothLock.readLock().lock();
            if (mBluetooth == null) {
                Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
                return;
            }
            int st = mBluetooth.getState();
            if (st != BluetoothAdapter.STATE_BLE_ON) {
                if (DBG) Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: " +
                         BluetoothAdapter.nameForState(st));
                return;
            }
            if (!mEnableExternal && !isBleAppPresent() &&
                !isBluetoothPersistedStateOnBluetooth()) {
                Slog.i(TAG, "Bluetooth was disabled while enabling BLE, disable BLE now");
                mEnable = false;
                mBluetooth.onBrEdrDown(mContext.getAttributionSource());
                return;
            }
            if (isBluetoothPersistedStateOnBluetooth() ||
                 mEnableExternal) {
                // This triggers transition to STATE_ON
                mBluetooth.updateQuietModeStatus(mQuietEnable,
                        mContext.getAttributionSource());
                mBluetooth.onLeServiceUp(mContext.getAttributionSource());
                persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Unable to call onServiceUp", e);
        } finally {
            mBluetoothLock.readLock().unlock();
        }
    }

然后会走到AdapterService$onLeServiceUp,发出下面一个message

        @Override
        public void onLeServiceUp(AttributionSource source) {
            AdapterService service = getService();
            if (service == null
                    || !Utils.checkCallerIsSystemOrActiveUser(TAG)
                    || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
                return;
            }
            enforceBluetoothPrivilegedPermission(service);
            service.mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
        }
  • BleOnState状态下,接收到USER_TURN_ON的message,调用mAdapterService.startBrEdrStartup(),并将目标状态设置为TurningOnState;
  • 调用TurningOnState的enter方法,发出一个超时处理的message,并调用mAdapterService.startProfileServices()
  • 启动所有的Profileservice,当最后一个ProfileService启动成功后,会发出BREDR_STARTED的消息
  • TurningOnState状态下接收到BREDR_STARTED的消息,将目标状态设置为OnState
  • 迁移过程中,首先执行TurningOnState状态的exit方法,移除超时处理的message,再执行到OnState的enter方法

至此,打开蓝牙开关的状态机迁移过程就完成了,关闭的过程则是相反的。

         +------   Off  <-----+
         |                    |
         v                    |
  TurningBleOn   TO--->   TurningBleOff
         |                  ^ ^
         |                  | |
         +----->        ----+ |
                  BleOn       |
         +------        <---+ O
         v                  | T
     TurningOn  TO---->  TurningOff
         |                    ^
         |                    |
         +----->   On   ------+

前面讲的可能有点乱,没事,有图:

 

也可以新建一个Bt_Enable.puml文件,去生成uml图。

如下为Bt_Enable.puml的code部分。

@startuml

participant BluetoothAdapter
participant BluetoothManagerService as BMS

BluetoothAdapter -> BMS : enable
activate BMS
BMS -> BMS : sendEnableMsg
BluetoothAdapter <-- BMS : return true
note over BMS
handle message MESSAGE_ENABLE
end note
BMS -> BMS : handleEnable
BMS -> AdapterService : doBind
deactivate BMS

AdapterService -> AdapterService : static
activate AdapterService
participant com_android_bluetooth_btservice_AdapterService as AdapterService_jni
AdapterService -> AdapterService_jni : System.loadLibrary("bluetooth_qti_jni")
AdapterService_jni -> AdapterService_jni : JNI_OnLoad
AdapterService <-- AdapterService_jni
AdapterService -> AdapterService_jni : classInitNative
AdapterService_jni -> AdapterService_jni : classInitNative
AdapterService <-- AdapterService_jni
deactivate AdapterService

AdapterService -> AdapterService : onCreate
activate AdapterService
create "AdapterService$AdapterServiceBinder" as AdapterServiceBinder
AdapterService -> AdapterServiceBinder : new AdapterServiceBinder(this)
create Vendor
AdapterService -> Vendor : new Vendor(this)
create com_android_bluetooth_btservice_vendor as Vendor_jni
Vendor -> Vendor_jni : classInitNative()
Vendor_jni -> Vendor_jni : classInitNative
Vendor_jni --> AdapterService
participant AdapterState
AdapterService -> AdapterState : AdapterState.make(this)
AdapterState -> AdapterState : new AdapterState
control OffState
control TurningBleOnState
control BleOnState
control TurningOnState
control OnState
control TurningOffState
control TurningBleOffState
activate AdapterState
participant StateMachine
AdapterState -> StateMachine : super(TAG)
StateMachine -> StateMachine : initStateMachine
activate StateMachine
create "StateMachine$SmHandler" as smHandler
StateMachine -> smHandler : new SmHandler
smHandler -> smHandler : addState(mHaltingState, null)
smHandler -> smHandler : addState(mQuittingState, null)
StateMachine <-- smHandler
deactivate StateMachine
AdapterState <-- StateMachine
AdapterState -> StateMachine : "addState(mOnState)\naddState(mBleOnState)\naddState(mOffState)\naddState(mTurningOnState)\naddState(mTurningOffState)\naddState(mTurningBleOnState)\naddState(mTurningBleOffState)"
StateMachine -> smHandler : 若干mSmHandler\n.addState(state, null)
smHandler -> smHandler : 若干addState
AdapterState <-- smHandler
AdapterState -> StateMachine : setInitialState(mOffState)
StateMachine -> smHandler : mSmHandler\n.setInitialState(initialState)
smHandler -> smHandler : setInitialState
note over StateMachine, smHandler
The invoke from StateMachine to SmHandler will be not written later.
end note
AdapterState <-- smHandler
AdapterState -> StateMachine : start
StateMachine -> smHandler : completeConstruction
note over smHandler
initialize mStateStack and mTempStateStack
add initial state into mTempStateStack
Sending SM_INIT_CMD message
end note
AdapterState <-- smHandler
deactivate AdapterState
AdapterService <-- AdapterState
create JniCallbacks
AdapterService -> JniCallbacks : new JniCallbacks
AdapterService -> AdapterService_jni : initNative
AdapterService_jni -> AdapterService_jni : initNative
AdapterService <-- AdapterService_jni
AdapterService -> Vendor : mVendor.init()
Vendor -> Vendor_jni : initNative()
Vendor_jni -> Vendor_jni : initNative
Vendor_jni --> AdapterService
deactivate AdapterService
AdapterService --> BMS : return true


note over smHandler
handle message asynchronously
end note
smHandler -> smHandler : handleMessage
activate smHandler
note over smHandler
handle message
SM_INIT_CMD
end note
smHandler -> smHandler : invokeEnterMethods(0)
smHandler -> OffState : enter
deactivate smHandler

...

AdapterService --> BMS : onServiceConnected callback from system
activate BMS
BMS -> BMS : send MESSAGE_BLUETOOTH_SERVICE_CONNECTED,\nmsg.arg1 = SERVICE_IBLUETOOTH
BMS -> AdapterService : mBluetooth.registerCallback(mBluetoothCallback,mContext.getAttributionSource())
AdapterService -> AdapterService : service.mCallbacks.register(callback)
BMS <-- AdapterService
BMS <-> AdapterServiceBinder : mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service))
BMS -> AdapterServiceBinder : mBluetooth.enable(mQuietEnable, mContext.getAttributionSource())
deactivate BMS

AdapterServiceBinder -> AdapterService : service.enable()
AdapterService -> AdapterService : enable(false)
activate AdapterService
AdapterService -> AdapterState : mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON)
deactivate AdapterService
AdapterState -> smHandler : sendMessage
note over smHandler
handle message
AdapterState.BLE_TURN_ON
end note
smHandler -> smHandler : handleMessage
activate smHandler
smHandler -> smHandler : msgProcessedState = processMsg(msg)
smHandler -> OffState : curStateInfo.state.processMessage(msg)
OffState -> smHandler : transitionTo(mTurningBleOnState)
smHandler -> smHandler : performTransitions
smHandler -> smHandler : setupTempStateStackWithStatesToEnter(destState)
smHandler -> OffState : invokeExitMethods(commonStateInfo)
smHandler -> smHandler : moveTempStateStackToStateStack()
smHandler -> TurningBleOnState : invokeEnterMethods(stateStackEnteringIndex)
TurningBleOnState -> TurningBleOnState : enter
TurningBleOnState -> AdapterService : mAdapterService.updateAdapterState(mPrevState, currState)
AdapterService -> BMS : onBluetoothStateChange
BMS -> BMS : send MESSAGE_BLUETOOTH_STATE_CHANGE message
activate BMS
note over BMS
handle message
MESSAGE_BLUETOOTH_STATE_CHANGE
end note
BMS -> BMS : bluetoothStateChangeHandler
BMS -> BMS : sendBleStateChanged(prevState, newState)
BMS --> TurningBleOnState
deactivate BMS
TurningBleOnState -> AdapterService : mAdapterService.bringUpBle()
deactivate smHandler

activate AdapterService
create Config
AdapterService -> Config : Config.init(getApplicationContext())
Config -> Config : profiles.add(config.mClass)
note over Config
Adding A2dpService
Adding HidHostService
Adding PanService
Adding GattService
Adding BluetoothMapService
Adding HidDeviceService
Adding BluetoothOppService
Adding BluetoothPbapService
Adding HearingAidService
Profile BATService Not added 
end note
AdapterService -> JniCallbacks : mJniCallbacks.init(mBondStateMachine, mRemoteDevices)
JniCallbacks  -> JniCallbacks : init
note over AdapterService
Start Gatt service
end note
create GattService
AdapterService -> GattService : setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON)
create com_android_bluetooth_gatt as GattService_jni
GattService -> GattService_jni : System.loadLibrary("bluetooth_qti_jni")
GattService -> GattService_jni : classInitNative
GattService_jni -> GattService_jni : classInitNative
GattService -> GattService : onCreate
create ProfileService
GattService -> ProfileService : super
ProfileService -> ProfileService : onCreate
ProfileService -> GattService : initBinder()
create "GattService$BluetoothGattBinder" as BluetoothGattBinder
GattService -> BluetoothGattBinder : new BluetoothGattBinder
GattService -> GattService : onStartCommand
activate GattService
GattService -> ProfileService : super.onStartCommand(intent, flags, startId)
ProfileService -> ProfileService : doStart
activate ProfileService
ProfileService -> AdapterService : mAdapterService.addProfile(this)
AdapterService -> AdapterService : send MESSAGE_PROFILE_SERVICE_REGISTERED message
note over AdapterService
handle message
MESSAGE_PROFILE_SERVICE_REGISTERED
end note
activate AdapterService
AdapterService -> AdapterService : registerProfileService((ProfileService) msg.obj)
AdapterService -> AdapterService : mRegisteredProfiles.add(profile)
deactivate AdapterService
AdapterService --> ProfileService
ProfileService -> GattService : mProfileStarted = start()
activate GattService
GattService -> GattService_jni : initializeNative
GattService_jni -> GattService_jni : initializeNative
deactivate GattService
ProfileService -> AdapterService : mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON)
deactivate ProfileService
deactivate GattService
AdapterService -> AdapterService : send MESSAGE_PROFILE_SERVICE_STATE_CHANGED message
note over AdapterService
handle message
MESSAGE_PROFILE_SERVICE_STATE_CHANGED
end note
activate AdapterService
AdapterService -> AdapterService : processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1)
AdapterService -> AdapterService : mRunningProfiles.add(profile)
AdapterService -> AdapterService_jni : enableNative
AdapterService_jni -> AdapterService_jni : enableNative
AdapterService <-- AdapterService_jni
deactivate AdapterService
deactivate AdapterService

AdapterService_jni <-- : adapter_state_change_callback
AdapterService_jni -> JniCallbacks : sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,(jint)status)
JniCallbacks -> AdapterService : mAdapterService.stateChangeCallback(status)
AdapterService -> AdapterState : send AdapterState.BLE_STARTED message

AdapterState -> smHandler : sendMessage
note over smHandler
handle message
AdapterState.BLE_STARTED
end note
smHandler -> smHandler : handleMessage
activate smHandler
smHandler -> smHandler : msgProcessedState = processMsg(msg)
smHandler -> TurningBleOnState : curStateInfo.state.processMessage(msg)
TurningBleOnState -> smHandler : transitionTo(mBleOnState)
smHandler -> smHandler : performTransitions
smHandler -> smHandler : setupTempStateStackWithStatesToEnter(destState)
smHandler -> TurningBleOnState : invokeExitMethods(commonStateInfo)
smHandler -> smHandler : moveTempStateStackToStateStack()
smHandler -> BleOnState : invokeEnterMethods(stateStackEnteringIndex)
BleOnState -> BleOnState : enter
BleOnState -> AdapterService : mAdapterService.updateAdapterState(mPrevState, currState)
AdapterService -> BMS : onBluetoothStateChange
BMS -> BMS : send MESSAGE_BLUETOOTH_STATE_CHANGE message
activate BMS
note over BMS
handle message
MESSAGE_BLUETOOTH_STATE_CHANGE
end note
BMS -> BMS : bluetoothStateChangeHandler
BMS -> BMS : continueFromBleOnState
BMS -> AdapterServiceBinder : mBluetooth.onLeServiceUp(mContext.getAttributionSource())
AdapterServiceBinder -> AdapterService : service.mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON)
AdapterService -> AdapterState : send USER_TURN_ON message
AdapterState -> smHandler : sendMessage
AdapterService --> BMS
BMS -> BMS : sendBleStateChanged(prevState, newState)
BMS --> TurningBleOnState
deactivate BMS
BleOnState --> smHandler
deactivate smHandler

note over smHandler
handle message
USER_TURN_ON
end note
smHandler -> smHandler : handleMessage
activate smHandler
smHandler -> smHandler : msgProcessedState = processMsg(msg)
smHandler -> BleOnState : curStateInfo.state.processMessage(msg)
BleOnState -> AdapterService : mAdapterService.startBrEdrStartup()
AdapterService -> Vendor : mVendor.bredrStartup()
Vendor -> Vendor_jni : bredrstartupNative()
Vendor_jni --> BleOnState
BleOnState -> smHandler : transitionTo(mTurningOnState)
smHandler -> smHandler : performTransitions
smHandler -> smHandler : setupTempStateStackWithStatesToEnter(destState)
smHandler -> BleOnState : invokeExitMethods(commonStateInfo)
smHandler -> smHandler : moveTempStateStackToStateStack()
smHandler -> TurningOnState : invokeEnterMethods(stateStackEnteringIndex)
TurningOnState -> TurningOnState : enter
TurningOnState -> AdapterService : mAdapterService.updateAdapterState(mPrevState, currState)
AdapterService -> BMS : onBluetoothStateChange
BMS -> BMS : send MESSAGE_BLUETOOTH_STATE_CHANGE message
activate BMS
note over BMS
handle message
MESSAGE_BLUETOOTH_STATE_CHANGE
end note
BMS -> BMS : bluetoothStateChangeHandler
BMS -> BMS : sendBleStateChanged(prevState, newState)
BMS --> TurningOnState
deactivate BMS
TurningOnState -> AdapterService : mAdapterService.startProfileServices()
AdapterService -> AdapterService : setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON)
AdapterService -> AdapterService : setProfileServiceState
note over AdapterService
Calling setProfileServiceState for: HeadsetService
Calling setProfileServiceState for: A2dpService
Calling setProfileServiceState for: HidHostService
Calling setProfileServiceState for: PanService
Calling setProfileServiceState for: BluetoothMapService
Calling setProfileServiceState for: HidDeviceService
Calling setProfileServiceState for: BluetoothOppService
Calling setProfileServiceState for: BluetoothPbapService
Calling setProfileServiceState for: HearingAidService
end note
...

note over ProfileService
when last ProfileService started
end note
ProfileService -> AdapterService : mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON)
...
AdapterService -> AdapterService : send MESSAGE_PROFILE_SERVICE_STATE_CHANGED message
note over AdapterService
handle message
MESSAGE_PROFILE_SERVICE_STATE_CHANGED
end note
AdapterService -> AdapterService : processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1)
note over AdapterService
All profile services started..
end note

AdapterService -> AdapterService : initProfileServices()
AdapterService -> AdapterState : send AdapterState.BREDR_STARTED message
AdapterState -> smHandler : sendMessage
deactivate smHandler

note over smHandler
handle message
BREDR_STARTED
end note
smHandler -> smHandler : handleMessage
activate smHandler
smHandler -> smHandler : msgProcessedState = processMsg(msg)
smHandler -> TurningOnState : curStateInfo.state.processMessage(msg)
TurningOnState -> smHandler : transitionTo(mOnState)
smHandler -> smHandler : performTransitions
smHandler -> smHandler : setupTempStateStackWithStatesToEnter(destState)
smHandler -> TurningOnState : invokeExitMethods(commonStateInfo)
smHandler -> smHandler : moveTempStateStackToStateStack()
smHandler -> OnState : invokeEnterMethods(stateStackEnteringIndex)
OnState -> OnState : enter
OnState -> AdapterService : mAdapterService.updateAdapterState(mPrevState, currState)
AdapterService -> BMS : onBluetoothStateChange
BMS -> BMS : send MESSAGE_BLUETOOTH_STATE_CHANGE message
activate BMS
note over BMS
handle message
MESSAGE_BLUETOOTH_STATE_CHANGE
end note
BMS -> BMS : bluetoothStateChangeHandler
BMS -> BMS : sendBluetoothStateCallback(isUp)
BMS -> BMS: mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp)
BMS -> BMS : send MESSAGE_BLUETOOTH_STATE_CHANGE message
BMS -> BMS : sendBleStateChanged(prevState, newState)
BMS --> OnState
deactivate BMS
deactivate smHandler

note over BMS
handle message
MESSAGE_BLUETOOTH_STATE_CHANGE
end note
BMS -> BMS : bluetoothStateChangeHandler
note over BMS
prevState == newState
return
end note

@enduml

你可能感兴趣的:(Android,Bluetooth,android)