从按下Android设备的电源键,启动顺序大致如下:
- Bootloader引导,加载、启动Kernel;
- 创建init进程,在不同启动阶段做不同的事;
- 创建Zygote进程;
- 创建SystemServer;
从Android 8开始,google引入了Treble后,相关的架构都基本上是Framework和vendor hal通过hidl service通信。从Android 11开始,google又引入了适用于HAL的AIDL,不过蓝牙还是用的hidl。
可以先找一台手机,执行下面命令看一下:
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博客 | 袁辉辉的技术博客。
在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
OffStateTurningOnState
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