栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 11 BT 配对流程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 11 BT 配对流程

这里记录上层应用的调用流程 !!!

packages/apps/TvSettings/Settings/src/com/android/tv/settings/accessories/BluetoothDevicePairer.java


    
    public void startPairing(BluetoothDevice device) {
        startPairing(device, true);
    }


    private void startPairing(BluetoothDevice device, boolean isManual) {
        // TODO check if we're already paired/bonded to this device

        // cancel auto-mode if applicable
        mAutoMode = !isManual;

        mTarget = device;

        if (isInProgress()) {
            throw new RuntimeException("Pairing already in progress, you must cancel the " +
                    "previous request first");
        }

        mHandler.removeCallbacksAndMessages(null);

        mNextStageTimestamp = SystemClock.elapsedRealtime() +
                (mAutoMode ? DELAY_AUTO_PAIRING : DELAY_MANUAL_PAIRING);
        mHandler.sendEmptyMessageDelayed(MSG_PAIR,
                mAutoMode ? DELAY_AUTO_PAIRING : DELAY_MANUAL_PAIRING);  
// 发送MSG_PAIR

        setStatus(STATUS_WAITING_TO_PAIR);
    }


    public BluetoothDevicePairer(Context context, EventListener listener) {
        mContext = context.getApplicationContext();
        mListener = listener;

        addBluetoothDeviceCriteria();

        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_PAIR:
                        startBonding();   //@ start Bonding
                        break;
                    case MSG_START:
                        start();
                        break;
                    default:
                        Log.d(TAG, "No handler case available for message: " + msg.what);
                }
            }
        };
    }



    private void startBonding() {
        stopScanning();
        setStatus(STATUS_PAIRING);
        if (mTarget.getBondState() != BluetoothDevice.BOND_BONDED) {
            registerlinkStatusReceiver();

            // create bond (pair) to the device
            mTarget.createBond();
        } else {
            onBonded();
        }
    }



frameworks/base/core/java/android/bluetooth/BluetoothDevice.java

    
    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public boolean createBond() {
        return createBond(TRANSPORT_AUTO);
    }



    
    @UnsupportedAppUsage
    public boolean createBond(int transport) {
        return createBondOutOfBand(transport, null);
    }


    
    public boolean createBondOutOfBand(int transport, OobData oobData) {
        final IBluetooth service = sService;
        if (service == null) {
            Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
            return false;
        }
        try {
            return service.createBond(this, transport, oobData);
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        }
        return false;
    }


private static volatile IBluetooth sService;

这里通过AIDL通信,从Settings APK进场调用到 Bluetooth.APK进程

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

        @Override
        public boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
            AdapterService service = getService();
            if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond")) {
                return false;
            }

            enforceBluetoothAdminPermission(service);

            return service.createBond(device, transport, oobData);
        }

    boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
        if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
            return false;
        }

        mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device));

        // Pairing is unreliable while scanning, so cancel discovery
        // Note, remove this when native stack improves
        cancelDiscoveryNative();

        Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
//@ 向状态机发送BondStateMachine.CREATE_BOND消息
        msg.obj = device;
        msg.arg1 = transport;

        if (oobData != null) {
            Bundle oobDataBundle = new Bundle();
            oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData);
            msg.setData(oobDataBundle);
        }
        mBondStateMachine.sendMessage(msg);
        return true;
    }

packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java

    private BondStateMachine(AdapterService service, AdapterProperties prop,
            RemoteDevices remoteDevices) {
        super("BondStateMachine:");
        addState(mStableState);
        addState(mPendingCommandState);
        mRemoteDevices = remoteDevices;
        mAdapterService = service;
        mAdapterProperties = prop;
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        setInitialState(mStableState);
    }

初始化状态为mStableState

private class StableState extends State {
        @Override
        public void enter() {
            infoLog("StableState(): Entering Off State");
        }

        @Override
        public synchronized boolean processMessage(Message msg) {

            BluetoothDevice dev = (BluetoothDevice) msg.obj;

            switch (msg.what) {

                case CREATE_BOND:
                    OobData oobData = null;
                    if (msg.getData() != null) {
                        oobData = msg.getData().getParcelable(OOBDATA);
                    }
//createBond !!!
                    createBond(dev, msg.arg1, oobData, true);
                    break;
                case REMOVE_BOND:
                    removeBond(dev, true);
                    break;
                case BONDING_STATE_CHANGE:
                    int newState = msg.arg1;
                
                    if (newState == BluetoothDevice.BOND_BONDING) {
                        sendIntent(dev, newState, 0);
                        transitionTo(mPendingCommandState);
                    } else if (newState == BluetoothDevice.BOND_NONE) {
                    
                        sendIntent(dev, newState, 0);
                    } else {
                        Log.e(TAG, "In stable state, received invalid newState: "
                                + state2str(newState));
                    }
                    break;
                case UUID_UPDATe:
                    if (mPendingBondedDevices.contains(dev)) {
                        sendIntent(dev, BluetoothDevice.BOND_BONDED, 0);
                    }
                    break;
                case CANCEL_BOND:
                default:
                    Log.e(TAG, "Received unhandled state: " + msg.what);
                    return false;
            }
            return true;
        }
    }

    private boolean createBond(BluetoothDevice dev, int transport, OobData oobData,
            boolean transition) {
        if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
            infoLog("Bond address is:" + dev);
            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
            boolean result;
            if (oobData != null) {
                result = mAdapterService.createBondOutOfBandNative(addr, transport, oobData);
            } else {
                result = mAdapterService.createBondNative(addr, transport);
            }
            BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
                    mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
                    BluetoothDevice.BOND_BONDING,
                    oobData == null ? BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN
                            : BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_OOB_DATA_PROVIDED,
                    BluetoothProtoEnums.UNBOND_REASON_UNKNOWN);
            if (!result) {
                BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
                        mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
                        BluetoothDevice.BOND_NONE, BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN,
                        BluetoothDevice.UNBOND_REASON_REPEATED_ATTEMPTS);
                // Using UNBOND_REASON_REMOVED for legacy reason
                sendIntent(dev, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED);
                return false;
            } else if (transition) {
                transitionTo(mPendingCommandState);
            }
            return true;
        }
        return false;
    }

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

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


native boolean createBondNative(byte[] address, int transport);

//native 接口调用到JNI
packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address,
                                 jint transport) {
  ALOGV("%s", __func__);

  if (!sBluetoothInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (addr == NULL) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
  env->ReleaseByteArrayElements(address, addr, 0);
  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

#通过sBluetoothInterface接口调用到Bluedroid协议栈,下一篇学习。。。。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/346179.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号