Android Framework 音频子系统(09)耳麦插拔之流程分析

该系列文章总纲链接:专题分纲目录 Android Framework 音频子系统​​​​​​​


本章关键点总结 & 说明:

本章节主要关注➕ 以上思维导图左上 耳麦插拔 部分 即可。本章节主要分析耳麦插拔流程,耳机发生插拔后,android是如何在framework层处理的。同时本章节 涉及输入子系统会写的相对简单一些,详细可参考输入子系统的专题链接:专题分纲目录 Android Framework 输入子系统

对于耳麦的插拔,Android有两种模式,可以使用input子系统,也可以使用state dev(uevent)上报拔插操作。说明如下:

  • 输入子系统:可以上报按键事件也可以上报开关事件(EV_SW),事件类型包括headset、headPhone、lineOut。对于输入设备都需要指定能产生同步类事件EV_SYN. 对于按键事件,输入子系统还需要设置按键值的范围,但是对于开关类事件不需要设置。
  • switch class子系统:通过uevent向用户空间发送数据,Android中有个线程专门监听这类事件。使用switch dev子系统时,名字必须要设置为"h2w",Android系统监听/sys/class/switch/h2w这个虚拟设备。

具体使用哪种操作 取决于config_useDevInputEventForAudioJack 这个配置值,定义在config.xml文件中,如下:

...  
    <!-- When true use the linux /dev/input/event subsystem to detect the switch changes
         on the headphone/microphone jack. When false use the older uevent framework. -->
    <bool name="config_useDevInputEventForAudioJack">false</bool>
...

该值为true时使用input子系统, 为false时使用uevent机制,该值在下述文件中定义, 后一个文件会覆盖前一个文件:

frameworks/base/core/res/res/values/config.xml
device/"平台厂商"/frameworks/base/core/res/res/values/config.xml

接下来我么对两种模式进行分析,两种模式前半段不一致,后半段处理是一致的。主要就是分析这样一个流程:底层的耳麦插拔是如何把事件一层层上报,最终通过ActivityManagerService将消息广播出去的过程。


1 前半段分析(两种模式到WiredAccessoryManager中updateLocked方法)

1.1 使用input子系统的流程(从input子系统到WiredAccessoryManager中updateLocked方法)

input子系统通过InputReader开始读取事件并处理。代码如下:

void InputReader::loopOnce() {
    //...
    //获取事件
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
    { // acquire lock
        //...
        //处理事件
        processEventsLocked(mEventBuffer, count);
        //...
    } // release lock

    // Send out a message that the describes the changed input devices.
    if (inputDevicesChanged) {
        mPolicy->notifyInputDevicesChanged(inputDevices);
    }
    mQueuedListener->flush();
}

InputReader线程 通过EventHub中的getEvent方法 从驱动中获取事件后使用processEventsLocked开始处理,processEventsLocked实现如下:

void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    for (const RawEvent* rawEvent = rawEvents; count;) {
        int32_t type = rawEvent->type;
        size_t batchSize = 1;
        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
            //...
            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
        } else {
            //...
        }
        count -= batchSize;
        rawEvent += batchSize;
    }
}

这里继续分析processEventsForDeviceLocked的实现,代码如下:

void InputReader::processEventsForDeviceLocked(int32_t deviceId,
        const RawEvent* rawEvents, size_t count) {
    //...
    InputDevice* device = mDevices.valueAt(deviceIndex);
    //...
    device->process(rawEvents, count);
}

继续分析InputDevice的process方法,代码如下:

void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    size_t numMappers = mMappers.size();
    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
        if (mDropUntilNextSync) {
            //...
        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
            //...
        } else {
            for (size_t i = 0; i < numMappers; i++) {
                InputMapper* mapper = mMappers[i];
                mapper->process(rawEvent);
            }
        }
    }
}

对于swicth事件来说,这里的map是SwitchInputMapper,它的process函数实现如下:

void SwitchInputMapper::process(const RawEvent* rawEvent) {
    switch (rawEvent->type) {
    case EV_SW:
        processSwitch(rawEvent->code, rawEvent->value);
        break;

    case EV_SYN:
        if (rawEvent->code == SYN_REPORT) {
            sync(rawEvent->when);
        }
    }
}

继续分析processSwitch,代码如下:

void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
    if (switchCode >= 0 && switchCode < 32) {
        if (switchValue) {
            mSwitchValues |= 1 << switchCode;
        } else {
            mSwitchValues &= ~(1 << switchCode);
        }
        mUpdatedSwitchMask |= 1 << switchCode;
    }
}

这里主要是通过mSwitchValues的值进行状态存储,我们继续分析sync的实现,代码如下:

void SwitchInputMapper::sync(nsecs_t when) {
    if (mUpdatedSwitchMask) {
        uint32_t updatedSwitchValues = mSwitchValues & mUpdatedSwitchMask;
        NotifySwitchArgs args(when, 0, updatedSwitchValues, mUpdatedSwitchMask);
        getListener()->notifySwitch(&args);
        mUpdatedSwitchMask = 0;
    }
}

这里的getListener()->notifySwitch(&args)实际上就是InputDispatcher的notifySwitch方法,代码实现如下:

void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
    uint32_t policyFlags = args->policyFlags;
    policyFlags |= POLICY_FLAG_TRUSTED;
    mPolicy->notifySwitch(args->eventTime,
            args->switchValues, args->switchMask, policyFlags);
}

这里的mPolicy->notifySwitch 经过JNI的回调最终会调用到Java层的InputManagerService中的notifySwitch方法,代码如下:

// Native callback.
private void notifySwitch(long whenNanos, int switchValues, int switchMask) {
    if ((switchMask & SW_LID_BIT) != 0) {
        final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0);
        mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
    }

    if ((switchMask & SW_CAMERA_LENS_COVER_BIT) != 0) {
        final boolean lensCovered = ((switchValues & SW_CAMERA_LENS_COVER_BIT) != 0);
        mWindowManagerCallbacks.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered);
    }
    //mUseDevInputEventForAudioJack在这里被配置成true,会走该分支
    if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) {
        mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
                switchMask);
    }
}

这里继续分析notifyWiredAccessoryChanged,代码实现如下:

@Override
public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask) {
    synchronized (mLock) {
        int headset;
        mSwitchValues = (mSwitchValues & ~switchMask) | switchValues;
        switch (mSwitchValues &
            (SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT)) {
            case 0:
                headset = 0;
                break;

            case SW_HEADPHONE_INSERT_BIT:
                headset = BIT_HEADSET_NO_MIC;
                break;

            case SW_LINEOUT_INSERT_BIT:
                headset = BIT_LINEOUT;
                break;

            case SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT:
                headset = BIT_HEADSET;
                break;

            case SW_MICROPHONE_INSERT_BIT:
                headset = BIT_HEADSET;
                break;

            default:
                headset = 0;
                break;
        }
        updateLocked(NAME_H2W,
            (mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) | headset);
    }
}

这里调用到了updateLocked方法了。接下来的分析我们在后半段分析时继续。

1.2 使用uevent机制的流程(从uevent到WiredAccessoryManager中updateLocked方法)

在systemserver中的startOtherServices中关于WiredAccessoryManager的创建和使用如下:

private void startOtherServices() {
    final Context context = mSystemContext;
	//...
        if (!disableMedia) {
            try {
                //关键点1
                inputManager.setWiredAccessoryCallbacks(
                        new WiredAccessoryManager(context, inputManager));
            } catch (Throwable e) {
                reportWtf("starting WiredAccessoryManager", e);
            }
        }
	//...
	final InputManagerService inputManagerF = inputManager;
	//...
	try {
		//关键点2
		if (inputManagerF != null) inputManagerF.systemRunning();
	} catch (Throwable e) {
		reportWtf("Notifying InputManagerService running", e);
	}
	//...
}

@1 WiredAccessoryManager创建

WiredAccessoryManager的构造器代码实现如下:

public WiredAccessoryManager(Context context, InputManagerService inputManager) {
    //这里涉及三个服务:电源子系统、输入输出子系统、音频子系统
    PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryManager");
    mWakeLock.setReferenceCounted(false);
    mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    mInputManager = inputManager;
    mUseDevInputEventForAudioJack =
            context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
    mObserver = new WiredAccessoryObserver();
}

这里的WiredAccessoryObserver是继承UEventObserver类的,UEventObserver实现为空,WiredAccessoryObserver的构造器代码如下:

public WiredAccessoryObserver() {
    mUEventInfo = makeObservedUEventList();
}

这里 makeObservedUEventList 的 代码实现如下:

private List<UEventInfo> makeObservedUEventList() {
    List<UEventInfo> retVal = new ArrayList<UEventInfo>();
    UEventInfo uei;

    //这里只监听这三个UEventInfo对应的事件,驱动程序通过uevent上报事件也只能上报这三个事件之一
    // Monitor h2w
    if (!mUseDevInputEventForAudioJack) {
                    //用于监听名为"h2w"这个Switch class驱动中创建的虚拟文件                                     
                    //./devices/virtual/switch/h2w
                    //./class/switch/h2w
        uei = new UEventInfo(NAME_H2W, BIT_HEADSET, BIT_HEADSET_NO_MIC, BIT_LINEOUT);
        if (uei.checkSwitchExists()) {
            retVal.add(uei);
        }
    }

    // Monitor USB
    uei = new UEventInfo(NAME_USB_AUDIO, BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL, 0);
    if (uei.checkSwitchExists()) {
        retVal.add(uei);
    } 
    uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0, 0);
    if (uei.checkSwitchExists()) {
        retVal.add(uei);
    } else {
        uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, 0, 0);
        if (uei.checkSwitchExists()) {
            retVal.add(uei);
        }
    }
    return retVal;
}

@2 inputManagerF的systemRunning()函数分析

inputManagerF.systemRunning()代码实现如下:

public void systemRunning() {
    //...
    if (mWiredAccessoryCallbacks != null) {
        mWiredAccessoryCallbacks.systemReady();
    }
}

这里systemReady代码实现如下:

@Override
public void systemReady() {
    synchronized (mLock) {
        mWakeLock.acquire();
        Message msg = mHandler.obtainMessage(MSG_SYSTEM_READY, 0, 0, null);
        mHandler.sendMessage(msg);
    }
}

处理MSG_SYSTEM_READY消息的handler代码如下:

private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_NEW_DEVICE_STATE:
                setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
                mWakeLock.release();
                break;
            case MSG_SYSTEM_READY:
                onSystemReady();
                mWakeLock.release();
                break;
        }
    }
};

这里会调用到onSystemReady,代码实现如下:

private void onSystemReady() {
    if (mUseDevInputEventForAudioJack) {
        int switchValues = 0;
        if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_HEADPHONE_INSERT) == 1) {
            switchValues |= SW_HEADPHONE_INSERT_BIT;
        }
        if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_MICROPHONE_INSERT) == 1) {
            switchValues |= SW_MICROPHONE_INSERT_BIT;
        }
        if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_LINEOUT_INSERT) == 1) {
            switchValues |= SW_LINEOUT_INSERT_BIT;
        }
        notifyWiredAccessoryChanged(0, switchValues,
                SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT);
    }
    mObserver.init();
}

继续分析mObserver的init()方法,代码实现如下:

void init() {
    //...
    for (int i = 0; i < mUEventInfo.size(); ++i) {
        UEventInfo uei = mUEventInfo.get(i);
        startObserving("DEVPATH="+uei.getDevPath());
    }
}

这里继续分析startObserving,代码实现如下:

public final void startObserving(String match) {
    final UEventThread t = getThread();
    t.addObserver(match, this);
}

继续看getThread的实现,代码如下:

private static UEventThread getThread() {
    synchronized (UEventObserver.class) {
        if (sThread == null) {
            sThread = new UEventThread();
            sThread.start();
        }
        return sThread;
    }
}

这里执行start时,会调用到UEventThread的run方法,代码实现如下:

public void run() {
    nativeSetup();
    while (true) {
        //...
        //等待事件,native层实现,从系统底层接收消息
        String message = nativeWaitForNextEvent();
        if (message != null) {
            //发送消息
            sendEvent(message);
        }
    }
}

发送消息实现如下:

private void sendEvent(String message) {
    //...
    if (!mTempObserversToSignal.isEmpty()) {
        final UEvent event = new UEvent(message);
        final int N = mTempObserversToSignal.size();
        for (int i = 0; i < N; i++) {
            final UEventObserver observer = mTempObserversToSignal.get(i);
            observer.onUEvent(event);
        }
        mTempObserversToSignal.clear();
    }
}

继续分析 observer的onUEvent(...)方法的实现,为空,这里会调用到子类WiredAccessoryObserver的实现,代码如下:

@Override
public void onUEvent(UEventObserver.UEvent event) {
    try {
        String devPath = event.get("DEVPATH");
        String name = event.get("SWITCH_NAME");
        int state = Integer.parseInt(event.get("SWITCH_STATE"));
        synchronized (mLock) {
            updateStateLocked(devPath, name, state);
        }
    } catch (NumberFormatException e) {
        Slog.e(TAG, "Could not parse switch state from event " + event);
    }
}

继续分析updateStateLocked,代码实现如下:

private void updateStateLocked(String devPath, String name, int state) {
    for (int i = 0; i < mUEventInfo.size(); ++i) {
        UEventInfo uei = mUEventInfo.get(i);
        if (devPath.equals(uei.getDevPath())) {
            updateLocked(name, uei.computeNewHeadsetState(mHeadsetState, state));
            return;
        }
    }
}

这里调用到了updateLocked方法了。接下来的分析我们在后半段分析时继续。


2 后半段分析( 从WiredAccessoryManager中updateLocked方法到上层ActivityManagerService发送广播)

WiredAccessoryManager的updateLocked代码实现如下:

private void updateLocked(String newName, int newState) {
    //...
    mWakeLock.acquire();
	//获得并发送message
    Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
            mHeadsetState, newName);
    mHandler.sendMessage(msg);
    mHeadsetState = headsetState;
}

这里的handler对于消息MSG_NEW_DEVICE_STATE的处理如下:

private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
@Override
public void handleMessage(Message msg) {
    switch (msg.what) {
        case MSG_NEW_DEVICE_STATE:
            setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
            mWakeLock.release();
            break;
        case MSG_SYSTEM_READY:
            onSystemReady();
            mWakeLock.release();
            break;
    }
}

这里关注setDevicesState的实现,代码如下:

private void setDevicesState(
        int headsetState, int prevHeadsetState, String headsetName) {
    synchronized (mLock) {
        int allHeadsets = SUPPORTED_HEADSETS;
        for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
            if ((curHeadset & allHeadsets) != 0) {
                setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState, headsetName);
                allHeadsets &= ~curHeadset;
            }
        }
    }
}

这里关注setDeviceStateLocked的实现,代码如下:

private void setDeviceStateLocked(int headset,
        int headsetState, int prevHeadsetState, String headsetName) {
    if ((headsetState & headset) != (prevHeadsetState & headset)) {
        int outDevice = 0;
        int inDevice = 0;
        int state;

        if ((headsetState & headset) != 0) {
            state = 1;
        } else {
            state = 0;
        }

        if (headset == BIT_HEADSET) {
            outDevice = AudioManager.DEVICE_OUT_WIRED_HEADSET;
            inDevice = AudioManager.DEVICE_IN_WIRED_HEADSET;
        } else if (headset == BIT_HEADSET_NO_MIC){
            outDevice = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
        } else if (headset == BIT_LINEOUT){
            outDevice = AudioManager.DEVICE_OUT_LINE;
        } else if (headset == BIT_USB_HEADSET_ANLG) {
            outDevice = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
        } else if (headset == BIT_USB_HEADSET_DGTL) {
            outDevice = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
        } else if (headset == BIT_HDMI_AUDIO) {
            outDevice = AudioManager.DEVICE_OUT_HDMI;
        } else {
            Slog.e(TAG, "setDeviceState() invalid headset type: "+headset);
            return;
        }
        if (outDevice != 0) {
          //进入了Audio系统,设置有线设备的连接状态
          mAudioManager.setWiredDeviceConnectionState(outDevice, state, headsetName);
        }
        if (inDevice != 0) {
          mAudioManager.setWiredDeviceConnectionState(inDevice, state, headsetName);
        }
    }
}

这里关注mAudioManager的setWiredDeviceConnectionState方法实现,代码如下:

public void setWiredDeviceConnectionState(int device, int state, String name) {
    IAudioService service = getService();
    try {
        service.setWiredDeviceConnectionState(device, state, name);
    } catch (RemoteException e) {
        Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e);
    }
}

继续分析 setWiredDeviceConnectionState,代码实现如下:

public void setWiredDeviceConnectionState(int device, int state, String name) {
    synchronized (mConnectedDevices) {
        int delay = checkSendBecomingNoisyIntent(device, state);
        queueMsgUnderWakeLock(mAudioHandler,
                MSG_SET_WIRED_DEVICE_CONNECTION_STATE,device,state,name,delay);
    }
}

这里的queueMsgUnderWakeLock代码实现如下:

private void queueMsgUnderWakeLock(Handler handler, int msg,
        int arg1, int arg2, Object obj, int delay) {
    final long ident = Binder.clearCallingIdentity();
    mAudioEventWakeLock.acquire();
    Binder.restoreCallingIdentity(ident);
    sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
}

handler对于MSG_SET_WIRED_DEVICE_CONNECTION_STATE消息进行处理,代码如下:

@Override
public void handleMessage(Message msg) {
    switch (msg.what) {
        case MSG_SET_DEVICE_VOLUME:
            setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
            break;
        //...
        case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
            onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);
            mAudioEventWakeLock.release();
            break;
        //...
    }
}

onSetWiredDeviceConnectionState的代码实现如下:

private void onSetWiredDeviceConnectionState(int device, int state, String name)
{
    synchronized (mConnectedDevices) {
        //...
        //关键点1:声道切换入口
        handleDeviceConnection((state == 1), device, (isUsb ? name : ""));
        if (state != 0) {
            //...
            if ((device & mSafeMediaVolumeDevices) != 0) {
                sendMsg(mAudioHandler,MSG_CHECK_MUSIC_ACTIVE,SENDMSG_REPLACE,0,0,null,MUSIC_ACTIVE_POLL_PERIOD_MS);
            }
            //...
        } else {
            //...
        }
        if (!isUsb && (device != AudioSystem.DEVICE_IN_WIRED_HEADSET)) {
            //关键点2:通过AMS上报intent
            sendDeviceConnectionIntent(device, state, name);
        }
    }
}

从这里开始我们有两个关键点需要关注,声道切换入口handleDeviceConnection 和 给AMS上报intent的sendDeviceConnectionIntent。 

@1 继续分析handleDeviceConnection,代码实现如下:

private boolean handleDeviceConnection(boolean connected, int device, String params) {
    synchronized (mConnectedDevices) {
        boolean isConnected = (mConnectedDevices.containsKey(device) &&
                (params.isEmpty() || mConnectedDevices.get(device).equals(params)));

        if (isConnected && !connected) {
            AudioSystem.setDeviceConnectionState(device,
                                          AudioSystem.DEVICE_STATE_UNAVAILABLE,
                                          mConnectedDevices.get(device));
             mConnectedDevices.remove(device);
             return true;
        } else if (!isConnected && connected) {
             AudioSystem.setDeviceConnectionState(device,
                                                  AudioSystem.DEVICE_STATE_AVAILABLE,
                                                  params);
             mConnectedDevices.put(new Integer(device), params);
             return true;
        }
    }
    return false;
}

这里会调用AudioSystem的setDeviceConnectionState方法,它的JNI映射关系为:

{"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState}

继续分析android_media_AudioSystem_setDeviceConnectionState的实现,代码如下:

static jint
android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
{
    const char *c_address = env->GetStringUTFChars(device_address, NULL);
    int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
                                          static_cast <audio_policy_dev_state_t>(state),
                                          c_address));
    env->ReleaseStringUTFChars(device_address, c_address);
    return (jint) status;
}

这里专注分析Native层AudioSystem的setDeviceConnectionState,代码实现如下:

status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
                                               audio_policy_dev_state_t state,
                                               const char *device_address)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    const char *address = "";
    //...
    if (device_address != NULL) {
        address = device_address;
    }
    return aps->setDeviceConnectionState(device, state, address);
}

这里返回的是AudioPolicyManager的setDeviceConnectionState方法,代码实现如下:

status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
                                                          audio_policy_dev_state_t state,
                                                  const char *device_address)
{
    return setDeviceConnectionStateInt(device, state, device_address);
}

在这里我们只需要知道从Java层AudioService的handleDeviceConnection方法最终可以直接调用到Native层AudioPolicyManager的setDeviceConnectionStateInt,后面我们会专门对setDeviceConnectionStateInt部分代码进行详细的解读。

@2 继续分析sendDeviceConnectionIntent,代码实现如下:

private void sendDeviceConnectionIntent(int device, int state, String name)
{
    //构建一个Intent结构,然后向应用程序广播它,注册对这个Intent感兴趣的App就会收到它
    Intent intent = new Intent();
    intent.putExtra("state", state);
    intent.putExtra("name", name);
    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    //...
    //intent其他处理
    //...
    try {
        
        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
    } finally {
        //...
    }
}

到这里,通过构建一个Intent结构,然后向应用程序广播它,接下来注册对这个Intent感兴趣的App就会收到它,控制权交给APP。后面会以案例形式接收并处理该intent。

发布了289 篇原创文章 · 获赞 47 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/vviccc/article/details/105394043