Android8.0 蓝牙系统

版权声明:未经本人同意,不得转载 https://blog.csdn.net/u013928208/article/details/83474385

Android 提供支持经典蓝牙和蓝牙低功耗的默认蓝牙堆栈。借助蓝牙,Android 设备可以创建个人区域网络,以便通过附近的蓝牙设备发送和接收数据,在 Android 4.3 及更高版本中,Android 蓝牙堆栈可提供实现蓝牙低功耗 (BLE) 的功能。要充分利用 BLE API,请遵循 Android 蓝牙 HCI 要求。具有合格芯片组的 Android 设备可以实现经典蓝牙或同时实现经典蓝牙和 BLE。BLE 不能向后兼容较旧版本的蓝牙芯片组。在 Android 8.0 中,原生蓝牙堆栈完全符合蓝牙 5 的要求。要使用可用的蓝牙 5 功能,该设备需要具有符合蓝牙 5 要求的芯片组。

在这里插入图片描述

处于应用框架级别的是应用代码,它使用 android.bluetooth API 与蓝牙硬件进行交互。此代码在内部通过 Binder IPC 机制调用蓝牙进程。蓝牙系统服务(位于 packages/apps/Bluetooth 中)被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。此应用通过 JNI 调用原生蓝牙堆栈。与 android.bluetooth 相关联的 JNI 代码位于 packages/apps/Bluetooth/jni 中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用蓝牙堆栈。系统在 AOSP 中提供了默认蓝牙堆栈,它位于 system/bt 中。该堆栈会实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义。供应商设备使用硬件接口设计语言 (HIDL) 与蓝牙堆栈交互。HIDL 定义了蓝牙堆栈和供应商实现之间的接口。要生成蓝牙 HIDL 文件,请将蓝牙接口文件传递到 HIDL 生成工具中。接口文件位于 hardware/interfaces/bluetooth 下。Android 8.0 蓝牙堆栈是一个完全限定的蓝牙堆栈。限定列表位于蓝牙 SIG 网站上的 QDID 97584 下。核心蓝牙堆栈位于 system/bt 下。

1. 蓝牙管理服务

frameworks\base\core\java\android\bluetooth\BluetoothProfile.java
蓝牙配置文件均实现了BluetoothProfile接口

public interface BluetoothProfile { ....... 
 			public interface ServiceListener {......} //回调接口
 } //接口

frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
以BluetoothHeadset为例, IBluetoothManager是AIDL文件,实现体为BluetoothManagerService

 /*package*/ BluetoothHeadset(Context context, ServiceListener l) {
        mContext = context;
        mServiceListener = l; //上述的回调接口
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        IBluetoothManager mgr = mAdapter.getBluetoothManager(); //作为BluetoothAdapter的代理
        if (mgr != null) {
            try {
                //mBluetoothStateChangeCallback是一个IBluetoothStateChangeCallback
                //此回调主要处理来自BluetoothManagerService的蓝牙状态改变
                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); //注册回调
            } catch (RemoteException e) {
                Log.e(TAG,"",e);
            }
        }

        doBind(); //绑定Profile
    }

frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
向 BluetoothManagerService 注册添加Profile

 boolean doBind() {
        try {
            //mConnection的类型为IBluetoothProfileServiceConnection
            return mAdapter.getBluetoothManager().bindBluetoothProfileService(
                    BluetoothProfile.HEADSET, mConnection); 
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to bind HeadsetService", e);
        }
        return false;
    }

frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java
由BluetoothManagerService回调处理

private final IBluetoothProfileServiceConnection mConnection
            = new IBluetoothProfileServiceConnection.Stub()  {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "Proxy object connected");
            //返回一个Service 类型为 IBluetoothHeadset
            mService = IBluetoothHeadset.Stub.asInterface(Binder.allowBlocking(service));
            mHandler.sendMessage(mHandler.obtainMessage(
                    MESSAGE_HEADSET_SERVICE_CONNECTED));
        }
        @Override
        public void onServiceDisconnected(ComponentName className) {
            if (DBG) Log.d(TAG, "Proxy object disconnected");
            mService = null;
            mHandler.sendMessage(mHandler.obtainMessage(
                    MESSAGE_HEADSET_SERVICE_DISCONNECTED));
        }
    };

frameworks\base\core\java\android\bluetooth\BluetoothHeadset.java

 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_HEADSET_SERVICE_CONNECTED: {
                    if (mServiceListener != null) {
                        //调用BluetoothProfile的回调函数
                        mServiceListener.onServiceConnected(BluetoothProfile.HEADSET,
                                BluetoothHeadset.this);
                    }
                    break;
                }
                case MESSAGE_HEADSET_SERVICE_DISCONNECTED: {
                    if (mServiceListener != null) {
                        mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
                    }
                    break;
                }
            }
        }
    };

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
向BluetoothManagerService注册状态回调

  public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
        //交给BluetoothHandler(内部类)处理
        Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
        msg.obj = callback;
        mHandler.sendMessage(msg);
    }

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
mStateChangeCallbacks 是一个 RemoteCallbackList

 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK:
 {
       IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
       mStateChangeCallbacks.register(callback);
       break;
}

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
bindBluetoothProfileService在IBluetoothManager.aidl文件中定义
IBluetoothProfileServiceConnection 对应一个ProfileServiceConnections

    @Override
    public boolean bindBluetoothProfileService(int bluetoothProfile,
            IBluetoothProfileServiceConnection proxy) {
        synchronized (mProfileServices) {
            ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
            if (psc == null) {
                if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
                Intent intent = new Intent(IBluetoothHeadset.class.getName());
                psc = new ProfileServiceConnections(intent); //新建一个
                if (!psc.bindService()) return false;
                //放入键值映射集合
                mProfileServices.put(new Integer(bluetoothProfile), psc);
            }
        }
        //交给 BluetoothHandler 去做
        // Introducing a delay to give the client app time to prepare
        Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
        addProxyMsg.arg1 = bluetoothProfile;
        addProxyMsg.obj = proxy;
        mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
        return true;
    }

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
往 ProfileServiceConnections中加入IBluetoothProfileServiceConnection

 case MESSAGE_ADD_PROXY_DELAYED:
                {
                    ProfileServiceConnections psc = mProfileServices.get(
                            new Integer(msg.arg1));
                    IBluetoothProfileServiceConnection proxy =
                            (IBluetoothProfileServiceConnection) msg.obj;
                    psc.addProxy(proxy);
                    break;
                }

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
mService 是 ProfileServiceConnections 内部持有的 IBinder 远程对象

 private void addProxy(IBluetoothProfileServiceConnection proxy) {
            mProxies.register(proxy);
            if (mService != null) {
                try{
                    proxy.onServiceConnected(mClassName, mService); //执行上述回调
                } catch (RemoteException e) {
                    Slog.e(TAG, "Unable to connect to proxy", e);
                }
            } else { //服务为空,重新绑定自身 ProfileServiceConnections
                if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
                    Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
                    msg.obj = this;
                    mHandler.sendMessage(msg);
                }
            }
        }

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
重新bindService

        private boolean bindService() {
            if (mIntent != null && mService == null &&
                    //Connection conn 传的是 this
                    doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
                Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
                msg.obj = this;
                mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
                return true;
            }
            return false;
        }

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
绑定成功后,会对代理逐一执行onServiceConnected回调

 @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // remove timeout message
            mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
            mService = service;
            mClassName = className;
            ......
            mInvokingProxyCallbacks = true;

            final int n = mProxies.beginBroadcast();
            try {
                for (int i = 0; i < n; i++) {
                    try {
                        mProxies.getBroadcastItem(i).onServiceConnected(className, service);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "Unable to connect to proxy", e);
                    }
                }
            } finally {
                mProxies.finishBroadcast();
                mInvokingProxyCallbacks = false;
            }
        }

BluetoothManagerService主要为frameworks\base\core\java\android\bluetooth下的各种BluetoothProfile协议子类提供服务管理,实际充当的是BluetoothAdapter的代理,BluetoothAdapter提供系统API给开发者使用,同时驱动系统蓝牙应用工作。

2. 蓝牙适配器

frameworks\base\core\java\android\bluetooth\BluetoothAdapter.java
mService 类型为IBluetooth, managerService类型为BluetoothManagerService

 BluetoothAdapter(IBluetoothManager managerService) {
        try {
            mServiceLock.writeLock().lock();
            mService = managerService.registerAdapter(mManagerCallback); //注册
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            mServiceLock.writeLock().unlock();
        }
        mManagerService = managerService; //BluetoothManagerService
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
        mToken = new Binder(); //令牌
    }

packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java

private static class AdapterServiceBinder extends IBluetooth.Stub { ...... }

frameworks\base\core\java\android\bluetooth\BluetoothAdapter.java
蓝牙禁用

    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public boolean disable() {
        try {
            return mManagerService.disable(ActivityThread.currentPackageName(), true);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java

 private void handleDisable() {
        try {
            mBluetoothLock.readLock().lock();
            if (mBluetooth != null) {
                if (DBG) Slog.d(TAG,"Sending off request.");
                if (!mBluetooth.disable()) {
                    Slog.e(TAG,"IBluetooth.disable() returned false");
                }
            }
        } finally {
            mBluetoothLock.readLock().unlock();
        }
    }

packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java
调用 AdapterServiceBinder 的 disable

  public boolean disable() {
            if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
                (!Utils.checkCaller())) {
                Log.w(TAG, "disable() - Not allowed for non-active user and non system user");
                return false;
            }

            AdapterService service = getService();
            if (service == null) return false;
            return service.disable();
        }

packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java
AdapterService的 disable

 boolean disable() {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");

        debugLog("disable() called...");
        //最终交给状态机处理
        Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_OFF);
        mAdapterStateMachine.sendMessage(m);
        return true;
    }

packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterState.java
状态机对应的处理状态

private class OnState extends State {
        ......
        @Override
        public boolean processMessage(Message msg) {
            AdapterProperties adapterProperties = mAdapterProperties;
            ......
            switch(msg.what) {
               case BLE_TURN_OFF:
                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_OFF);
                   mPendingCommandState.setTurningOff(true);
                   transitionTo(mPendingCommandState); //状态转换

                   // Invoke onBluetoothDisable which shall trigger a
                   // setScanMode to SCAN_MODE_NONE
                   Message m = obtainMessage(SET_SCAN_MODE_TIMEOUT);
                   sendMessageDelayed(m, PROPERTY_OP_DELAY);
                   adapterProperties.onBluetoothDisable(); //禁用
                   break;

               case USER_TURN_ON:
                   break;

               default:
                   return false;
            }
            return true;
        }
    }

在packages\apps\Bluetooth\src\com\android\bluetooth\下主要是蓝牙协议,适配服务,协议服务。整个协议和服务由状态机驱动执行。

3. 系统蓝牙设置

packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothSettings.java
BluetoothSettings是系统蓝牙操作界面

 @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mInitialScanStarted = false;
        mInitiateDiscoverable = true;

        final SettingsActivity activity = (SettingsActivity) getActivity();
        mSwitchBar = activity.getSwitchBar();

        mBluetoothEnabler = new BluetoothEnabler(activity, new SwitchBarController(mSwitchBar),
            mMetricsFeatureProvider, Utils.getLocalBtManager(activity),
            MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
        mBluetoothEnabler.setupSwitchController();
    }

packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothEnabler.java
蓝牙操作控制

 @Override
    public boolean onSwitchToggled(boolean isChecked) {
        if (maybeEnforceRestrictions()) {
            return true;
        }

        // Show toast message if Bluetooth is not allowed in airplane mode
        if (isChecked &&
                !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
            Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
            // Reset switch to off
            mSwitch.setChecked(false);
            return false;
        }

        mMetricsFeatureProvider.action(mContext, mMetricsEvent, isChecked);

        if (mLocalAdapter != null) {
            boolean status = mLocalAdapter.setBluetoothEnabled(isChecked); //开关蓝牙
            // If we cannot toggle it ON then reset the UI assets:
            // a) The switch should be OFF but it should still be togglable (enabled = True)
            // b) The switch bar should have OFF text.
            if (isChecked && !status) {
                mSwitch.setChecked(false);
                mSwitch.setEnabled(true);
                mSwitchWidget.updateTitle(false);
                return false;
            }
        }
        mSwitchWidget.setEnabled(false);
        return true;
    }

frameworks\base\packages\SettingsLib\src\com\android\settingslib\bluetooth\LocalBluetoothAdapter.java
mAdapter 是 BluetoothAdapter

 public boolean setBluetoothEnabled(boolean enabled) {
        boolean success = enabled
                ? mAdapter.enable() //开启
                : mAdapter.disable();
        return success;
    }

frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java
调用 BluetoothManagerService 的 enable 函数,最后将操作结果返回

 @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public boolean enable() {
        try {
            return mManagerService.enable(ActivityThread.currentPackageName());
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

4. 蓝牙HAL

packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java

  static {
        classInitNative();
    }

packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp

static void classInitNative(JNIEnv* env, jclass clazz) {
  jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
  android_bluetooth_UidTraffic.constructor =
      env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V");

  .....
  
  char value[PROPERTY_VALUE_MAX];
  property_get("bluetooth.mock_stack", value, "");

  const char* id =
      (strcmp(value, "1") ? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);

  hw_module_t* module;
  int err = hw_get_module(id, (hw_module_t const**)&module);

  if (err == 0) {
    hw_device_t* abstraction;
    err = module->methods->open(module, id, &abstraction); //加载蓝牙模块
    if (err == 0) {
      bluetooth_module_t* btStack = (bluetooth_module_t*)abstraction;
      sBluetoothInterface = btStack->get_bluetooth_interface();
    } else {
      ALOGE("Error while opening Bluetooth library");
    }
  } else {
    ALOGE("No Bluetooth Library found");
  }
}

packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
调用系统蓝牙堆栈处理 system/bt 目录下

static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
  ALOGV("%s", __func__);

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

5. 蓝牙数据传输

frameworks\base\core\java\android\bluetooth\BluetoothAdapter.java
通过套接进行数据交换传输 mSocket 是 BluetoothSocket

public BluetoothServerSocket listenUsingRfcommOn(int channel, boolean mitm,
            boolean min16DigitPin)
            throws IOException {
        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_RFCOMM, true, true, channel, mitm, min16DigitPin);
        int errno = socket.mSocket.bindListen();
        if (channel == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
            socket.setChannel(socket.mSocket.getPort());
        }
        if (errno != 0) {
            //TODO(BT): Throw the same exception error code
            // that the previous code was using.
            //socket.mSocket.throwErrnoNative(errno);
            throw new IOException("Error: " + errno);
        }
        return socket;
    }

frameworks\base\core\java\android\bluetooth\BluetoothSocket.java
通过IBluetooth 的 createSocketChannel,创建FD, 监听Socket连接

 /*package*/ int bindListen() {
        int ret;
        if (mSocketState == SocketState.CLOSED) return EBADFD;
        IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
        try {
            //创建Socket返回文件描述符
            mPfd = bluetoothProxy.createSocketChannel(mType, mServiceName,
                    mUuid, mPort, getSecurityFlags());
        } catch (RemoteException e) {
            Log.e(TAG, Log.getStackTraceString(new Throwable()));
            return -1;
        }

        // read out port number
        try {
            synchronized(this) {
                if(mSocketState != SocketState.INIT) return EBADFD;
                if(mPfd == null) return -1;
                FileDescriptor fd = mPfd.getFileDescriptor();
                mSocket = LocalSocket.createConnectedLocalSocket(fd);
                if (DBG) Log.d(TAG, "bindListen(), new LocalSocket.getInputStream()");
                mSocketIS = mSocket.getInputStream();
                mSocketOS = mSocket.getOutputStream();
            }
            int channel = readInt(mSocketIS);
            synchronized(this) {
                if(mSocketState == SocketState.INIT)
                    mSocketState = SocketState.LISTENING;
            }
            if (mPort <= -1) {
                mPort = channel;
            } // else ASSERT(mPort == channel)
            ret = 0;
        } catch (IOException e) {
            if (mPfd != null) {
                try {
                    mPfd.close();
                } catch (IOException e1) {
                    Log.e(TAG, "bindListen, close mPfd: " + e1);
                }
                mPfd = null;
            }
            return -1;
        }
        return ret;
    }

至此我们粗略的查看了蓝牙系统框架,可以看到,系统定义了不同的蓝牙协议的统一行为,让BluetoothAdapter作为交互中心,提供系统和应用交互的接口,BluetoothManagerService作为BluetoothAdapter的代理,对各种协议连接进行处理,Setting 目录的blutooth模块 借助 framwork下的SettingLib模块与 BluetoothAdapter进行交互,最终由系统应用Bluetooth目录下的服务负责与蓝牙底层协议和硬件交互。每一层协议都可以独立处理自己的逻辑,还可以自由得添加新的协议,可扩展性很高。我们就不去逐一分析各层协议的具体实现了,可以说蓝牙的用途是极广泛且重要的,不光用于数据传输,蓝牙耳机,心跳检测,血脂血糖检测,VR等。

猜你喜欢

转载自blog.csdn.net/u013928208/article/details/83474385