[Bluetooth] Android Bluetooth

危砚
2023-12-01

Bluetooth相关的服务在SystemServer.java中被启动。

                Slog.i(TAG, "Bluetooth Service");
                bluetooth = new BluetoothService(context);
                ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
                bluetooth.initAfterRegistration();

                if (!"0".equals(SystemProperties.get("system_init.startaudioservice"))) {
                    bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
                    ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
                                              bluetoothA2dp);
                    bluetooth.initAfterA2dpRegistration();
                }
                int airplaneModeOn = Settings.System.getInt(mContentResolver,
                        Settings.System.AIRPLANE_MODE_ON, 0);
                int bluetoothOn = Settings.Secure.getInt(mContentResolver,
                            Settings.Secure.BLUETOOTH_ON, 0);
                if (airplaneModeOn == 0 && bluetoothOn != 0) {
                    bluetooth.enable();        
                }

BluetoothService

frameworks/base/core/java/android/server/BluetoothService.java

    public synchronized void initAfterRegistration() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mBluetoothState = new BluetoothAdapterStateMachine(mContext, this, mAdapter);
        mBluetoothState.start();
        if (mContext.getResources().getBoolean
            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch) &&
            mBluetoothState.is_hot_off_enabled()) {
            mBluetoothState.sendMessage(BluetoothAdapterStateMachine.TURN_HOT);
        }    
        mEventLoop = mBluetoothState.getBluetoothEventLoop();
    }    

    /** Bring up BT and persist BT on in settings */
    public boolean enable() {
        return enable(true, true);
    }

    /**
     * Enable this Bluetooth device, asynchronously.
     * This turns on/off the underlying hardware.
     *
     * @param saveSetting If true, persist the new state of BT in settings
     * @param allowConnect If true, auto-connects device when BT is turned on
     *                     and allows incoming A2DP/HSP connections
     * @return True on success (so far)
     */
    public synchronized boolean enable(boolean saveSetting, boolean allowConnect) {
        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                "Need BLUETOOTH_ADMIN permission");

        // Airplane mode can prevent Bluetooth radio from being turned on.
        if (mIsAirplaneSensitive && isAirplaneModeOn() && !mIsAirplaneToggleable) {
            return false;
        }    
        mAllowConnect = allowConnect;
        mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_ON,
                                           saveSetting);
        return true;
    }    

BluetoothAdapter

BluetoothAdapterStateMachine

    BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
                                 BluetoothAdapter bluetoothAdapter) {                                                                                 
        super(TAG);
        mContext = context;
        mBluetoothService = bluetoothService;
        mEventLoop = new BluetoothEventLoop(context, bluetoothAdapter, bluetoothService, this);                                                       

        mBluetoothOn = new BluetoothOn();
        mSwitching = new Switching();  
        mHotOff = new HotOff();        
        mWarmUp = new WarmUp();        
        mPreWarmUp = new PreWarmUp();  
        mPowerOff = new PowerOff();    
        mPerProcessState = new PerProcessState();
    }


    private class PowerOff extends State { 
        @Override
        public void enter() {
            if (DBG) log("Enter PowerOff: " + getCurrentMessage().what);
        }
        @Override
        public boolean processMessage(Message message) {
            log("PowerOff process message: " + message.what);

            boolean retValue = HANDLED;    
            switch(message.what) {         
                case USER_TURN_ON:             
                    // starts turning on BT module, broadcast this out
                    broadcastState(BluetoothAdapter.STATE_TURNING_ON);
                    transitionTo(mPreWarmUp);      
                    if (prepareBluetooth()) {      
                        // this is user request, save the setting
                        if ((Boolean) message.obj) {   
                            persistSwitchSetting(true);    
                        }
                        // We will continue turn the BT on all the way to the BluetoothOn state
                        deferMessage(obtainMessage(TURN_ON_CONTINUE));
                    } else {
                        Log.e(TAG, "failed to prepare bluetooth, abort turning on");
                        transitionTo(mPowerOff);       
                        broadcastState(BluetoothAdapter.STATE_OFF);
                    }
                    break;
                case TURN_HOT:
                    if (prepareBluetooth()) {      
                        transitionTo(mPreWarmUp);      
                    }
                    break;
             }
        }

        /**
         * Turn on Bluetooth Module, Load firmware, and do all the preparation
         * needed to get the Bluetooth Module ready but keep it not discoverable
         * and not connectable.
         * The last step of this method sets up the local service record DB.
         * There will be a event reporting the status of the SDP setup.
         */
        private boolean prepareBluetooth() {
            if (mBluetoothService.enableNative() != 0) {
                return false;
            }

            // try to start event loop, give 2 attempts
            int retryCount = 2;
            boolean eventLoopStarted = false;
            while ((retryCount-- > 0) && !eventLoopStarted) {
                mEventLoop.start();
                // it may take a moment for the other thread to do its
                // thing.  Check periodically for a while.
                int pollCount = 5;
                while ((pollCount-- > 0) && !eventLoopStarted) {
                    if (mEventLoop.isEventLoopRunning()) {
                        eventLoopStarted = true;
                        break;
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        log("prepareBluetooth sleep interrupted: " + pollCount);
                        break;
                    }
                }


BluetoothA2dpService

frameworks/base/core/java/android/server/BluetoothA2dpService.java


 类似资料: