蓝牙配对笔记

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/sxj159753/article/details/86361445

显示列表

packages/apps/Settings/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java

DeviceListPreferenceFragment

初始化操作
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mLocalManager = Utils.getLocalBtManager(getActivity());
        if (mLocalManager == null) {
            Log.e(TAG, "Bluetooth is not supported on this device");
            return;
        }
        mLocalAdapter = mLocalManager.getBluetoothAdapter();
        //1.加载列表,父类抽象,子类(BluetoothSettings)实现
        addPreferencesForActivity();

        mDeviceListGroup = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
    }

看一下1
父类抽象,子类(BluetoothSettings)实现

code/8953_7120/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java
    @Override
    void addPreferencesForActivity() {
        addPreferencesFromResource(R.xml.bluetooth_settings);

        mPairedDevicesCategory = new PreferenceCategory(getPrefContext());
        mPairedDevicesCategory.setKey(KEY_PAIRED_DEVICES);
        mPairedDevicesCategory.setOrder(1);
        getPreferenceScreen().addPreference(mPairedDevicesCategory);

        mAvailableDevicesCategory = new BluetoothProgressCategory(getActivity());
        mAvailableDevicesCategory.setSelectable(false);
        mAvailableDevicesCategory.setOrder(2);
        getPreferenceScreen().addPreference(mAvailableDevicesCategory);

        mMyDevicePreference = new Preference(getPrefContext());
        mMyDevicePreference.setSelectable(false);
        mMyDevicePreference.setOrder(3);
        getPreferenceScreen().addPreference(mMyDevicePreference);

        setHasOptionsMenu(true);
    }

点击选项列表配对

/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java

    private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // User clicked on advanced options icon for a device in the list
            if (!(v.getTag() instanceof CachedBluetoothDevice)) {
                Log.w(TAG, "onClick() called for other View: " + v);
                return;
            }

            final CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
            Bundle args = new Bundle();
            args.putString(DeviceProfilesSettings.ARG_DEVICE_ADDRESS,
                    device.getDevice().getAddress());
                    
                    
            //2.1
            DeviceProfilesSettings profileSettings = new DeviceProfilesSettings();
            profileSettings.setArguments(args);
            profileSettings.show(getFragmentManager(),
                    DeviceProfilesSettings.class.getSimpleName());
        }
    };

https://blog.csdn.net/lwnlwn1/article/details/48023785

2.1 创建对话框

/home/songxijun/code/8953_7120/packages/apps/Settings/src/com/android/settings/bluetooth/DeviceProfilesSettings.java

DeviceProfilesSettings extends DialogFragment

// /8953_7120/packages/apps/Settings/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java

    void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
    
    
        btPreference.onClicked();
    }

进入 btPreference.onClicked();

    void onClicked() {
        int bondState = mCachedDevice.getBondState();

        if (mCachedDevice.isConnected()) {
            askDisconnect();
        } else if (bondState == BluetoothDevice.BOND_BONDED) {
            mCachedDevice.connect(true);
        } else if (bondState == BluetoothDevice.BOND_NONE) {
            //配对
            pair();
        }
    }

进入pair();

    private void pair() {
        if (!mCachedDevice.startPairing()) {
            Utils.showError(getContext(), mCachedDevice.getName(),
                    R.string.bluetooth_pairing_error_message);
        } else {
            final Context context = getContext();

            SearchIndexableRaw data = new SearchIndexableRaw(context);
            data.className = BluetoothSettings.class.getName();
            data.title = mCachedDevice.getName();
            data.screenTitle = context.getResources().getString(R.string.bluetooth_settings);
            data.iconResId = R.drawable.ic_settings_bluetooth;
            data.enabled = true;

            Index.getInstance(context).updateFromSearchIndexableData(data);
        }
    }

mCachedDevice.startPairing()

/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
    public boolean startPairing() {
        // Pairing is unreliable while scanning, so cancel discovery
        if (mLocalAdapter.isDiscovering()) {
            mLocalAdapter.cancelDiscovery();
        }

        if (!mDevice.createBond()) {
            return false;
        }

        mConnectAfterPairing = true;  // auto-connect after pairing
        return true;
    }

mDevice.createBond()

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

    public boolean createBond() {
        if (sService == null) {
            Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
            return false;
        }
        try {
            Log.i(TAG, "createBond() for device " + getAddress() +
                    " called by pid: " + Process.myPid() +
                    " tid: " + Process.myTid());
            return sService.createBond(this, TRANSPORT_AUTO);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

通过aidl调用到package/app目录中

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

        public boolean createBond(BluetoothDevice device, int transport) {
            if (!Utils.checkCallerAllowManagedProfiles(mService)) {
                Log.w(TAG, "createBond() - Not allowed for non-active user");
                return false;
            }

            AdapterService service = getService();
            if (service == null) return false;
            return service.createBond(device, transport, null);
        }

service.createBond(device, transport, null);

     boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
            "Need BLUETOOTH ADMIN permission");
        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
        if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
            return false;
        }
        // Multicast: Do not allow bonding while multcast
        A2dpService a2dpService = A2dpService.getA2dpService();
        if (a2dpService != null &&
            a2dpService.isMulticastFeatureEnabled() &&
            a2dpService.isMulticastOngoing(null)) {
            Log.i(TAG,"A2dp Multicast is ongoing, ignore bonding");
            return false;
        }

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

        Message msg = mBondStateMachine.obtainMessage(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;
    }

mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
这个状态机处理蓝牙适配器状态。

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

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

        @Override
        public 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(dev, msg.arg1, oobData, true);
                  break;
            ...
            }
            return true;
        }
    }

createBond

    private boolean createBond(BluetoothDevice dev, int transport, OobData oobData,
                               boolean transition) {
        if(mAdapterService == null) return false;
        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);
            }

            if (!result) {
                sendIntent(dev, BluetoothDevice.BOND_NONE,
                           BluetoothDevice.UNBOND_REASON_REMOVED);
                return false;
            } else if (transition) {
                transitionTo(mPendingCommandState);
            }
            return true;
        }
        return false;
    }

result = mAdapterService.createBondNative(addr, transport);

packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

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

    jbyte *addr;
    jboolean result = JNI_FALSE;

    if (!sBluetoothInterface) return result;

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

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

    return result;
}

int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr, transport);

/hardware/libhardware/include/hardware/bluetooth.h

int (*create_bond)(const bt_bdaddr_t *bd_addr, int transport);

猜你喜欢

转载自blog.csdn.net/sxj159753/article/details/86361445