Android 蓝牙(二) Bluetooth Settings 关闭流程详解

蓝牙关闭的流程和开启的流程差不多,下面简单分析一下流程:

1.BluetoothEnabler.java--->onSwitchToggled()

关闭和开启蓝牙的switchbar的监听状态存在与BluetoothEnable类中,当点击switchbar时,由于BluetoothEnabler implements SwitchWidgetController.OnSwitchChangeListener ,所以会调用onSwitchToggled

    @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) {
            //isChecked未false则关闭蓝牙
            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;
    }

2.LocalBluetoothAdapter.java--->setBluetoothEnabled()


    public boolean setBluetoothEnabled(boolean enabled) {
        //关闭时false,所以调用到BluetoothAdapter.java-->disable()
        boolean success = enabled
                ? mAdapter.enable()
                : mAdapter.disable();
 
        if (success) {
            setBluetoothStateInt(enabled
                ? BluetoothAdapter.STATE_TURNING_ON
                : BluetoothAdapter.STATE_TURNING_OFF);
        } else {
            if (Utils.V) {
                Log.v(TAG, "setBluetoothEnabled call, manager didn't return " +
                        "success for enabled: " + enabled);
            }
 
            syncBluetoothState();
        }
        return success;

3.BluetoothAdapter.java-->disable()

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

4..BluetoothManagerService.java--->disable()

public boolean disable(String packageName, boolean persist) throws RemoteException {
        final int callingUid = Binder.getCallingUid();
        final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;

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

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

            if (isEnabled() && mPermissionReviewRequired && !CtaManagerFactory.getInstance().
                makeCtaManager().isSystemApp(mContext, packageName)
                    && startConsentUiIfNeeded(packageName, callingUid,
                            BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
                return false;
            }
        }

        if (DBG) {
            Slog.d(TAG,"disable(): mBluetooth = " + mBluetooth +
                " mBinding = " + mBinding);
        }

        synchronized(mReceiver) {
            if (persist) {
                persistBluetoothSetting(BLUETOOTH_OFF);
            }
            mEnableExternal = false;
            sendDisableMsg(packageName);
        }
        return true;
    }

4.BluetoothManagerService.java--->sendDisableMsg()

发送MESSAGE_DISABLE消息

    private void sendDisableMsg(String packageName) {
        mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
        addActiveLog(packageName, false);
    }

接收MESSAGE_DISABLE消息

                case MESSAGE_DISABLE:
                    if (DBG) Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
                    mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                    if (mEnable && mBluetooth != null) {
                        waitForOnOff(true, false);
                        mEnable = false;
                        handleDisable();
                        waitForOnOff(false, false);
                    } else {
                        mEnable = false;
                        handleDisable();
                    }
                    break;

5.BluetoothManagerService.java--->handleDisable()

在这里会调用到IBluetooth的客户端代理类mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));

调用mBluetooth.enable()

    private void handleDisable() {
        try {
            mBluetoothLock.readLock().lock();
            if (mBluetooth != null) {
                if (DBG) Slog.d(TAG,"Sending off request.");
                //mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
                //是IBluetooth的客户端,服务端是AdapterService的一个内部类、
                //AdapterServiceBinder extends IBluetooth.Stub,
                if (!mBluetooth.disable()) {
                    Slog.e(TAG,"IBluetooth.disable() returned false");
                }
            }
        } catch (RemoteException e) {
            Slog.e(TAG,"Unable to call disable()",e);
        } finally {
            mBluetoothLock.readLock().unlock();
        }
    }

6.AdapterService.java--->AdapterServiceBinder --->disable()

AdapterService位于Bluetooth包下,其内部类AdapterServiceBinder extends IBluetooth.Stub

        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();
        }

7.AdapterService.java--->disable()

发送AdapterState.BLE_TURN_OFF信息

     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;
    }

8.AdapterState.java--->OnState

接收AdapterState.BLE_TURN_OFF信息

               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;

8.AdapterService.java--->onBluetoothDisable()

    void onBluetoothDisable() {
        // From STATE_ON to BLE_ON
        // When BT disable is invoked, set the scan_mode to NONE
        // so no incoming connections are possible

        //Set flag to indicate we are disabling. When property change of scan mode done
        //continue with disable sequence
        debugLog("onBluetoothDisable()");
        mBluetoothDisabling = true;
        if (getState() == BluetoothAdapter.STATE_TURNING_OFF) {
            // Turn off any Device Search/Inquiry
            mService.cancelDiscovery();
            setScanMode(AbstractionLayer.BT_SCAN_MODE_NONE);
        }
    }
    boolean setScanMode(int scanMode) {
        synchronized (mObject) {
            //setAdapterPropertyNatives是native方法
            return mService.setAdapterPropertyNative(
                    AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE, Utils.intToByteArray(scanMode));
        }
    }

猜你喜欢

转载自blog.csdn.net/liu362732346/article/details/81808323