android 蓝牙的enable流程

android 蓝牙的enable流程

    • 前提
    • APP
    • framework
    • Bluetooth.apk
    • END

本篇介绍从settings enable蓝牙的流程,按照蓝牙的代码的位置分成 APP层Framework层Bluetooth.apk三个部分。
这里的enable其实只是启动上层协议,使协议处于listen的状态。
蓝牙的driver的启动流程在下一篇博客中。
借用网上的一张图片,该篇只涉及左边半部分。
android 蓝牙的enable流程_第1张图片

前提

  1. 这篇文章的codes和分析的流程基于Android 7.0的Qcom8909平台。
  2. 该平台支撑传统蓝牙和BLE。

APP

android 蓝牙的enable流程_第2张图片
开关是个SwitchBar,监听事件callback到onSwitchChanged,调用mLocalAdapter.setBluetoothEnabled(isChecked),mLocalAdapter是个com.android.settingslib.bluetooth.LocalBluetoothAdapter的一个实例:

    public boolean enable() {
        return mAdapter.enable();
    }

这里的mAdapter是BluetoothAdapter的实例,在LocalBluetoothAdapter的构造函数中初始化。

framework

  1. 然后到framework层的BluetoothAdapter,该类api多多,简单来说就是分装了面向APP层的几乎所有蓝牙相关的API。
    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public boolean enable() {
        android.util.SeempLog.record(56);
        if (isEnabled()) {
            if (DBG) Log.d(TAG, "enable(): BT already enabled!");
            return true;
        }
        try {
            return mManagerService.enable(ActivityThread.currentPackageName());
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }
private final IBluetoothManager mManagerService;

这个mManagerService是BluetoothManagerService的binder的代理。

  1. BluetoothManagerService是在SystemServer中被拉起,跑在SystemServer进程中。
    public boolean enable(String packageName) throws RemoteException {
        final int callingUid = Binder.getCallingUid();
        final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;

        if (!callerSystem) {
            if (!checkIfCallerIsForegroundUser()) {
                Slog.w(TAG, "enable(): not allowed for non-active and non system user");
                return false;
            }

            mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                    "Need BLUETOOTH ADMIN permission");

            if (!isEnabled() && mPermissionReviewRequired
                    && startConsentUiIfNeeded(packageName, callingUid,
                            BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
                return false;
            }
        }

        if (DBG) {
            Slog.d(TAG,"enable(" + packageName + "):  mBluetooth =" + mBluetooth +
                    " mBinding = " + mBinding + " mState = " +
                    BluetoothAdapter.nameForState(mState));
        }

        synchronized(mReceiver) {
            mQuietEnableExternal = false;
            mEnableExternal = true;
            // waive WRITE_SECURE_SETTINGS permission check
            sendEnableMsg(false, packageName);
        }
        if (DBG) Slog.d(TAG, "enable returning");
        return true;
    }

先是做一些权限检查,然后:

    private void sendEnableMsg(boolean quietMode, String packageName) {
        mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
                             quietMode ? 1 : 0, 0));
        addActiveLog(packageName, true);
    }

看看Handler里怎么处理MESSAGE_ENABLE消息:

        case MESSAGE_ENABLE:
            if (DBG) {
                Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
            }
            mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
            mEnable = true;

            // Use service interface to get the exact state
            try {
                mBluetoothLock.readLock().lock();
                if (mBluetooth != null) {
                    int state = mBluetooth.getState();
                    if (state == BluetoothAdapter.STATE_BLE_ON) {
                        Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
                        mBluetooth.onLeServiceUp();

                        // waive WRITE_SECURE_SETTINGS permission check
                        long callingIdentity = Binder.clearCallingIdentity();
                        persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
                        Binder.restoreCallingIdentity(callingIdentity);
                        break;
                    }
               }
          } catch (RemoteException e) {
              Slog.e(TAG, "", e);
          } finally {
              mBluetoothLock.readLock().unlock();
          }

          mQuietEnable = (msg.arg1 == 1);
          if (mBluetooth == null) {
              handleEnable(mQuietEnable);
          } else {
              int state;
              try {
                  state = mBluetooth.getState();
              } catch (RemoteException e) {
                  Slog.e(TAG, "getState()", e);
                  break;
              }
              if(state == BluetoothAdapter.STATE_TURNING_OFF || state == BluetoothAdapter.STATE_BLE_TURNING_OFF)
                  waitForMonitoredOnOff(false, true);
              Message restartMsg = mHandler.obtainMessage(
                          MESSAGE_RESTART_BLUETOOTH_SERVICE);
             mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
        }
        break;

Bluetooth.apk

mBluetooth是IBluetooth类型的实例,IBluetooth是aidl,由AdapterService里的内部类AdapterServiceBinder继承实现,AdapterService是Bluetooth.apk里的类。如果支持BLE,那此时mBluetooth.getState()的返回值是BluetoothAdapter.STATE_BLE_ON, 所以下一步走到onLeServiceUp:

    public void onLeServiceUp() {
        Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
        mAdapterStateMachine.sendMessage(m);
    }

mAdapterStateMachine是AdapterState的实例, AdapterState是个状态机,继承自com.android.internal.util.StateMachine(对状态机有兴趣的请看我前面的博客,有三篇详细讲解状态机)。
所以发的消息USER_TURN_ON就要看目前是在哪个状态,便在哪个状态处理这个消息。
打开蓝牙,enable()前便已进入BleOnState状态,所以USER_TURN_ON消息也在此状态中处理:

    case USER_TURN_ON:
        notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON);
        adapterProperties.clearDisableFlag();
        mPendingCommandState.setTurningOn(true);
        transitionTo(mPendingCommandState);
        sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
        adapterService.startCoreServices();
        break;

可以看到进入了PendingCommandState状态,且adapterService.startCoreServices() :

    void startCoreServices()
    {
        debugLog("startCoreServices()");
        Class[] supportedProfileServices = Config.getSupportedProfiles();

        //Start profile services
        if (!mProfilesStarted && supportedProfileServices.length >0) {
            //Startup all profile services
            setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
        }else {
            Log.w(TAG,"startCoreProfiles(): Profile Services alreay started");
            mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STARTED));
        }
    }

其中Config.getSupportedProfiles()获取的是Config类中的SUPPORTED_PROFILES, 该变量的值在上一篇的讲bluetooth_jni的博客中顺带提过,在打开蓝牙,拉起Bluetooth进程,第一个会执行的可见方法中便会初始化且赋值,里面放的是支持的协议List。这里面包含了BLE的协议和传统蓝牙的协议,具体支持哪些协议在这里配置:packages/apps/Bluetooth/res/values/config.xml
知道了支持的协议,便是一个一个拉起各个service:

    @SuppressWarnings("rawtypes")
    private void setProfileServiceState(Class[] services, int state) {
        if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
            debugLog("setProfileServiceState() - Invalid state, leaving...");
            return;
        }

        int expectedCurrentState= BluetoothAdapter.STATE_OFF;
        int pendingState = BluetoothAdapter.STATE_TURNING_ON;
        if (state == BluetoothAdapter.STATE_OFF) {
            expectedCurrentState= BluetoothAdapter.STATE_ON;
            pendingState = BluetoothAdapter.STATE_TURNING_OFF;
        }
        Log.w(TAG, "Total profiles ="+ (services.length));

        for (int i=0; i <services.length;i++) {
            String serviceName = services[i].getName();
            String simpleName = services[i].getSimpleName();

            if (simpleName.equals("GattService")) continue;

            Integer serviceState = mProfileServicesState.get(serviceName);
            if(serviceState != null && serviceState != expectedCurrentState) {
                Log.w(TAG, "setProfileServiceState() - Unable to "
                    + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" )
                    + " service " + serviceName
                    + ". Invalid state: " + serviceState);
                continue;
            }

            Log.w(TAG, "setProfileServiceState() - "
                + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting")
                + " service " + serviceName);

            mProfileServicesState.put(serviceName,pendingState);
            Intent intent = new Intent(this,services[i]);
            intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
            intent.putExtra(BluetoothAdapter.EXTRA_STATE,state);
            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
            startService(intent);
        }
    }

进入各个协议的service后都进入listen状态,看是不是有设备要连接自己,比如有设备要传输音频过来,要先连接我方的OPP协议,那么这时我方OPP协议才能知道设备要连自己。这属于协议栈的分析,其中的代码流程分析不在此篇wiki中。

END

当在APP层enable蓝牙的流程就这样。

你可能感兴趣的:(Bluetooth)