android 耳机插拔流程

来源:互联网 发布:信息软件 编辑:程序博客网 时间:2024/06/09 14:29

SystemServer.java中:

private void startOtherServices() {// ...    traceBeginAndSlog("StartWiredAccessoryManager");    try {        // Listen for wired headset changes        inputManager.setWiredAccessoryCallbacks(                new WiredAccessoryManager(context, inputManager));//设置WiredAccessoryCallbacks    } catch (Throwable e) {        reportWtf("starting WiredAccessoryManager", e);    }// ...    final InputManagerService inputManagerF = inputManager;// ...    try {        // TODO(BT) Pass parameter to input manager        if (inputManagerF != null) inputManagerF.systemRunning();//调用systemRunning,这里先记下,下面会看到用途    } catch (Throwable e) {        reportWtf("Notifying InputManagerService running", e);    }}

先看WiredAccessoryManager对象的创建过程:
WiredAccessoryManager.java中:
构造函数:

public WiredAccessoryManager(Context context, InputManagerService inputManager) {    mContext = context;    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);//这里在config文件中配置,这里为false。    mObserver = new WiredAccessoryObserver();//创建WiredAccessoryObserver对象    IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);//并且添加了开机广播接收    filter.addAction("android.intent.action.LAUNCH_POWEROFF_ALARM");}

看下接收开机广播干嘛:但是发现并没有相关处理。
那么看下WiredAccessoryObserver()创建时干了什么:
WiredAccessoryObserver是WiredAccessoryManager的内部类

public WiredAccessoryObserver() {    mUEventInfo = makeObservedUEventList();//继续往下看}private List<UEventInfo> makeObservedUEventList() { //看起来就是用来获取要监听的UEvent    List<UEventInfo> retVal = new ArrayList<UEventInfo>();    UEventInfo uei;    // Monitor h2w    if (!mUseDevInputEventForAudioJack) {//这里是配置的mUseDevInputEventForAudioJack是false,所以监听h2w的UEvent事件了,如果是true,就不监听h2w的UEvent事件了。        uei = new UEventInfo(NAME_H2W, BIT_HEADSET, BIT_HEADSET_NO_MIC, BIT_LINEOUT);//这里就是一些耳机类型。其对应的UEvent信息创建在UEventInfo中。        if (uei.checkSwitchExists()) {            retVal.add(uei);        } else {            Slog.w(TAG, "This kernel does not have wired headset support");        }    }    // Monitor USB    uei = new UEventInfo(NAME_USB_AUDIO, BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL, 0);    if (uei.checkSwitchExists()) {        retVal.add(uei);    } else {        Slog.w(TAG, "This kernel does not have usb audio support");    }    // Monitor HDMI    //    // If the kernel has support for the "hdmi_audio" switch, use that.  It will be    // signalled only when the HDMI driver has a video mode configured, and the downstream    // sink indicates support for audio in its EDID.    //    // If the kernel does not have an "hdmi_audio" switch, just fall back on the older    // "hdmi" switch instead.    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);        } else {            Slog.w(TAG, "This kernel does not have HDMI audio support");        }    }    return retVal;}

下面看下UEventInfo:也是WiredAccessoryManager的内部类,里面指出了监听的节点。getDevPath()与getSwitchStatePath()。

private final class UEventInfo {    private final String mDevName;    private final int mState1Bits;    private final int mState2Bits;    private final int mStateNbits;    public UEventInfo(String devName, int state1Bits, int state2Bits, int stateNbits) {        mDevName = devName;        mState1Bits = state1Bits;        mState2Bits = state2Bits;        mStateNbits = stateNbits;    }    public String getDevName() { return mDevName; }    public String getDevPath() {        return String.format(Locale.US, "/devices/virtual/switch/%s", mDevName);    }    public String getSwitchStatePath() {        return String.format(Locale.US, "/sys/class/switch/%s/state", mDevName);//UEvent事件状态切换信息保存在该节点中。    }    public boolean checkSwitchExists() {        File f = new File(getSwitchStatePath());        return f.exists();    }    public int computeNewHeadsetState(int headsetState, int switchState) {//UEvent事件触发时执行,修改音频设置参数。        int preserveMask = ~(mState1Bits | mState2Bits | mStateNbits);        int setBits = ((switchState == 1) ? mState1Bits :                      ((switchState == 2) ? mState2Bits :                      ((switchState == mStateNbits) ? mStateNbits : 0)));        if (switchState == 3) {            num_hs_pole = "num_hs_pole=5";//这里参数代表的含义是什么?            setBits = mState1Bits;        } else if (switchState == 1) {            num_hs_pole = "num_hs_pole=4";//这里参数代表的含义是什么?         } else {            num_hs_pole = "NA";        }            return ((headsetState & preserveMask) | setBits);        }    }}

现在这个WiredAccessoryObserver是创建了,那它是什么启动监听的呢?
我们已经看完了WiredAccessoryManager对象的创建过程
再看setWiredAccessoryCallbacks过程,看看是不是在这个过程中启动的监听:
在InputManagerService.java中:

public void setWiredAccessoryCallbacks(WiredAccessoryCallbacks callbacks) {    mWiredAccessoryCallbacks = callbacks;//就是这么一句,仅仅是赋个值。那就看下mWiredAccessoryCallbacks用到了哪里?}

搜了一下:
第一处:

// Native callback.//这里是一个private的方法,外部是没法调用的,在类中也没有调用该方法的地方,那这个Native callback是什么意思?native层可以回调到这个方法?private void notifySwitch(long whenNanos, int switchValues, int switchMask) {    if (DEBUG) {        Slog.d(TAG, "notifySwitch: values=" + Integer.toHexString(switchValues)                + ", mask=" + Integer.toHexString(switchMask));    }    Log.d("qdd", "notifySwitch: values=" + Integer.toHexString(switchValues)                + ", mask=" + Integer.toHexString(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);    }    if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) {        Log.d("qdd", "notifySwitch: notifyWiredAccessoryChanged");        //这里回调notifyWiredAccessoryChanged方法,进去看下这个方法是干嘛的?是处理耳机状态改变的。而且config中配置mUseDevInputEventForAudioJack为false。        mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,switchMask);    }    if ((switchMask & SW_TABLET_MODE_BIT) != 0) {        SomeArgs args = SomeArgs.obtain();        args.argi1 = (int) (whenNanos & 0xFFFFFFFF);        args.argi2 = (int) (whenNanos >> 32);        args.arg1 = Boolean.valueOf((switchValues & SW_TABLET_MODE_BIT) != 0);        mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED,args).sendToTarget();    }}

第二处:

public void systemRunning() {//这个就是上面systemserver中设置完WiredAccessoryCallbacks后调用的。    if (DEBUG) {        Slog.d(TAG, "System ready.");    }    mNotificationManager = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);    mSystemReady = true;    IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);    filter.addAction(Intent.ACTION_PACKAGE_REMOVED);    filter.addAction(Intent.ACTION_PACKAGE_CHANGED);    filter.addAction(Intent.ACTION_PACKAGE_REPLACED);    filter.addDataScheme("package");    mContext.registerReceiver(new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            updateKeyboardLayouts();        }    }, filter, null, mHandler);    filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED);    mContext.registerReceiver(new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            reloadDeviceAliases();        }    }, filter, null, mHandler);    mHandler.sendEmptyMessage(MSG_RELOAD_DEVICE_ALIASES);    mHandler.sendEmptyMessage(MSG_UPDATE_KEYBOARD_LAYOUTS);    if (mWiredAccessoryCallbacks != null) {        mWiredAccessoryCallbacks.systemReady();//调用systemReady()方法;继续看下干嘛的?    }    ///M:[ALPS01762006]Delay the keyboard change notification until NotificationBar is ready @{    synchronized (mInputDevicesLock) {        if (!mPendingMessages.isEmpty()) {            Slog.d(TAG, "Input Manager has " + mPendingMessages.size() + " pending messages");            for (int i = 0 ; i < mPendingMessages.size() ; i++) {                mPendingMessages.get(i).sendToTarget();            }            mPendingMessages.clear();        }    }    /// @}}

WiredAccessoryManager.java中:

@Overridepublic void systemReady() {    synchronized (mLock) {        mWakeLock.acquire();        Log.d("qdd","systemReady --- sendmessage ---MSG_SYSTEM_READY");        Message msg = mHandler.obtainMessage(MSG_SYSTEM_READY, 0, 0, null);//发送消息,继续跟        mHandler.sendMessage(msg);    }}private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {    @Override    public void handleMessage(Message msg) {        switch (msg.what) {            case MSG_NEW_DEVICE_STATE:                Log.d("qdd","wiredAccessoryManager --- mHandler -- MSG_NEW_DEVICE_STATE --->setDevicesState : arg1 = " + msg.arg1 + ";arg2 = " + msg.arg2 + ";obj = " + (String)msg.obj);                setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);                mWakeLock.release();                break;            case MSG_SYSTEM_READY:                Log.d("qdd","wiredAccessoryManager --- mHandler -- MSG_SYSTEM_READY --->onSystemReady");                onSystemReady();//再继续跟                mWakeLock.release();                break;        }    }};private void onSystemReady() {    if (mUseDevInputEventForAudioJack) {//config中配置这里为false。        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;        }        Log.d("qdd","wiredAccessoryManager --- onSystemReady  --> notifyWiredAccessoryChanged switchValues = " + switchValues);        notifyWiredAccessoryChanged(0, switchValues,SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT);    }    Log.d("qdd","wiredAccessoryManager --- onSystemReady  --> mObserver.init()");    mObserver.init();//很好,这里看到mObserver了,跟下去。}void init() {    synchronized (mLock) {        if (LOG) Slog.v(TAG, "init()");        char[] buffer = new char[1024];        for (int i = 0; i < mUEventInfo.size(); ++i) {            UEventInfo uei = mUEventInfo.get(i);            try {                int curState;                FileReader file = new FileReader(uei.getSwitchStatePath());                int len = file.read(buffer, 0, 1024);                file.close();                curState = Integer.parseInt((new String(buffer, 0, len)).trim());                if (curState > 0) {                    Log.d("qdd","wiredAccessoryManager --- WiredAccessoryObserver -- init -->updateStateLocked");                    updateStateLocked(uei.getDevPath(), uei.getDevName(), curState);                }            } catch (FileNotFoundException e) {                Slog.w(TAG, uei.getSwitchStatePath() +" not found while attempting to determine initial switch state");            } catch (Exception e) {                Slog.e(TAG, "" , e);            }        }    }    // At any given time accessories could be inserted    // one on the board, one on the dock and one on HDMI:    // observe three UEVENTs    for (int i = 0; i < mUEventInfo.size(); ++i) {        UEventInfo uei = mUEventInfo.get(i);        startObserving("DEVPATH="+uei.getDevPath());//是的,有了,这里就是开始监听耳机的UEvent事件了。    }}

开启监听的过程就这样理清了,接下来看下监听是怎么处理的:
WiredAccessoryObserver中的回调方法:

@Overridepublic void onUEvent(UEventObserver.UEvent event) {    if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());    try {        String devPath = event.get("DEVPATH");        String name = event.get("SWITCH_NAME");        int state = Integer.parseInt(event.get("SWITCH_STATE"));//获取切换的状态        synchronized (mLock) {            Log.d("qdd","wiredAccessoryManager --- onUEvent -->updateStateLocked");            updateStateLocked(devPath, name, state);//更新状态,跟进去看下怎么处理的        }    } catch (NumberFormatException e) {        Slog.e(TAG, "Could not parse switch state from event " + event);    }}private void updateStateLocked(String devPath, String name, int state) {    for (int i = 0; i < mUEventInfo.size(); ++i) {        UEventInfo uei = mUEventInfo.get(i);        Log.d("qdd","wiredAccessoryManager --- updateStateLocked : devPath = " + devPath + " ; uei.getDevPath() = " + uei.getDevPath() + " ; ---> updateLocked");        if (devPath.equals(uei.getDevPath())) {            updateLocked(name, uei.computeNewHeadsetState(mHeadsetState, state));//继续跟            return;        }    }}/** * Compare the existing headset state with the new state and pass along accordingly. Note * that this only supports a single headset at a time. Inserting both a usb and jacked headset * results in support for the last one plugged in. Similarly, unplugging either is seen as * unplugging all. * * @param newName One of the NAME_xxx variables defined above. * @param newState 0 or one of the BIT_xxx variables defined above. */private void updateLocked(String newName, int newState) {    // Retain only relevant bits    int headsetState = newState & SUPPORTED_HEADSETS;    int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;    int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;    int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT);    boolean h2wStateChange = true;    boolean usbStateChange = true;    if (LOG) Slog.v(TAG, "newName=" + newName            + " newState=" + newState            + " headsetState=" + headsetState            + " prev headsetState=" + mHeadsetState);    if (mHeadsetState == headsetState) {        Log.e(TAG, "No state change.");        return;    }    // reject all suspect transitions: only accept state changes from:    // - a: 0 headset to 1 headset    // - b: 1 headset to 0 headset    if (h2w_headset == (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) {        Log.e(TAG, "Invalid combination, unsetting h2w flag");        h2wStateChange = false;    }    // - c: 0 usb headset to 1 usb headset    // - d: 1 usb headset to 0 usb headset    if (usb_headset_anlg == BIT_USB_HEADSET_ANLG && usb_headset_dgtl == BIT_USB_HEADSET_DGTL) {        Log.e(TAG, "Invalid combination, unsetting usb flag");        usbStateChange = false;    }    if (!h2wStateChange && !usbStateChange) {        Log.e(TAG, "invalid transition, returning ...");        return;    }    mWakeLock.acquire();    Log.i(TAG, "MSG_NEW_DEVICE_STATE");    Log.i("qdd", "updateLocked --- sendmessage --- MSG_NEW_DEVICE_STATE");    Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,mHeadsetState, "");//又是消息,继续跟。    mHandler.sendMessage(msg);    mHeadsetState = headsetState;}private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {    @Override    public void handleMessage(Message msg) {        switch (msg.what) {            case MSG_NEW_DEVICE_STATE:                Log.d("qdd","wiredAccessoryManager --- mHandler -- MSG_NEW_DEVICE_STATE --->setDevicesState : arg1 = " + msg.arg1 + ";arg2 = " + msg.arg2 + ";obj = " + (String)msg.obj);                setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);//继续跟                mWakeLock.release();                break;            case MSG_SYSTEM_READY:                Log.d("qdd","wiredAccessoryManager --- mHandler -- MSG_SYSTEM_READY --->onSystemReady");                onSystemReady();                mWakeLock.release();                break;        }    }};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;            }        }    }}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 (LOG)            Slog.v(TAG, "device "+ headsetName+((state == 1) ? " connected" : " disconnected"));        //ALPS00708321:add for AB=00->01, set device BIT_HEADSET will ingore and music will pause when plug in        // headset complete,so need delay to confirm set device BIT_HEADSET to Audio        if (prevHeadsetState == BIT_HEADSET_NO_MIC && headsetState == BIT_HEADSET && state == 0) {            try {                Thread.sleep(100);            } catch (InterruptedException e) {                // Ingore            }        }        Log.d(TAG, "WiredHeadset num_hs_pole is " + num_hs_pole);        if (state == 1){            if (num_hs_pole != "NA")                mAudioManager.setParameters(num_hs_pole);//这个参数是干什么的?跟到C++的代码,看不懂了        }        if (outDevice != 0) {            mAudioManager.setWiredDeviceConnectionState(outDevice, state, "", headsetName);//连接输出设备        }        if (inDevice != 0) {            mAudioManager.setWiredDeviceConnectionState(inDevice, state, "", headsetName);//连接输入设备,继续跟下,看看这个方法做什么的。        }        illegal_state = getIllegalHeadset();        if (49 == illegal_state) {            mHandler.postDelayed(new Runnable() {                public void run() {                    illegal_state = getIllegalHeadset();                    if (49 == illegal_state) {                        Slog.d(TAG, "show illegal Headset msg+++++++++++++");                        showheadsetToast();                        illegal_state = 0;                    } else {                        Slog.d(TAG, "don't show illegal Headset msg+++++++++++++");                        illegal_state = 0;                    }                }            }, 500);            //illegal_state = 0;        }    }}

最后调用的是AudioService.java中的setWiredDeviceConnectionState方法:

public void setWiredDeviceConnectionState(int type, int state, String address, String name,String caller) {    synchronized (mConnectedDevices) {        if (DEBUG_DEVICES) {            Slog.i(TAG, "setWiredDeviceConnectionState(" + state + " nm: " + name + " addr:" + address + ")");        }        int delay = checkSendBecomingNoisyIntent(type, state);        queueMsgUnderWakeLock(mAudioHandler,                                       MSG_SET_WIRED_DEVICE_CONNECTION_STATE,            //handler处理,跟这个消息                0,                0,                new WiredDeviceConnectionState(type, state, address, name, caller),                delay);    }}@Overridepublic void handleMessage(Message msg) {// ...    case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:    {   WiredDeviceConnectionState connectState = (WiredDeviceConnectionState)msg.obj;        onSetWiredDeviceConnectionState(connectState.mType, connectState.mState,        connectState.mAddress, connectState.mName, connectState.mCaller);   //跟下去;        mAudioEventWakeLock.release();    }        break;    // ...}private void onSetWiredDeviceConnectionState(int device, int state, String address,String deviceName, String caller) {    if (DEBUG_DEVICES) {        Slog.i(TAG, "onSetWiredDeviceConnectionState(dev:" + Integer.toHexString(device)                + " state:" + Integer.toHexString(state)                + " address:" + address                + " deviceName:" + deviceName                + " caller: " + caller + ");");    }    synchronized (mConnectedDevices) {    Log.d(TAG, "onSetWiredDeviceConnectionState:" + "device:" + device + ",state:" + state);        /**         * M: do not broadcast if headset is connected for ALPS00850163 @{         */        boolean shouldNotify = true;        if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) ||                    (device == AudioSystem.DEVICE_OUT_LINE))) {            /**             * M: do not setForceUse if headset is connected for             * ALPS00657344 @{             */            boolean isHeadphoneOff = (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);            boolean isHeadsetOn = mConnectedDevices.containsKey(new StringBuilder().append("0x")                    .append(AudioSystem.DEVICE_OUT_WIRED_HEADSET).append(":").toString());            if (isHeadphoneOff && isHeadsetOn) {                shouldNotify = false;                Log.d(TAG, "onSetWiredDeviceConnectionState() no need to setForceUse");            }            if (shouldNotify) {            // @}                setBluetoothA2dpOnInt(true);            /// M: ALPS00657344 @{            }            /** @} */        }        boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) ||                        (((device & AudioSystem.DEVICE_BIT_IN) != 0) &&                         ((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0));        if (!handleDeviceConnection(state == 1, device, address, deviceName)) {            // change of connection state failed, bailout            return;        }        if (state != 0) {            if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||                (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) ||                (device == AudioSystem.DEVICE_OUT_LINE)) {                setBluetoothA2dpOnInt(false);            }            if ((device & mSafeMediaVolumeDevices) != 0) {                sendMsg(mAudioHandler,                        MSG_CHECK_MUSIC_ACTIVE,                        SENDMSG_REPLACE,                        0,                        0,                        caller,                        MUSIC_ACTIVE_POLL_PERIOD_MS);            }            // Television devices without CEC service apply software volume on HDMI output            if (isPlatformTelevision() && ((device & AudioSystem.DEVICE_OUT_HDMI) != 0)) {                mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_HDMI;                checkAllFixedVolumeDevices();                if (mHdmiManager != null) {                    synchronized (mHdmiManager) {                        if (mHdmiPlaybackClient != null) {                            mHdmiCecSink = false;                            mHdmiPlaybackClient.queryDisplayStatus(mHdmiDisplayStatusCallback);                        }                    }                }            }        } else {            if (isPlatformTelevision() && ((device & AudioSystem.DEVICE_OUT_HDMI) != 0)) {                if (mHdmiManager != null) {                    synchronized (mHdmiManager) {                        mHdmiCecSink = false;                    }                }            }        }        if (!isUsb && device != AudioSystem.DEVICE_IN_WIRED_HEADSET) {            //可以看到耳机插入,这里发送广播给上层app去接收。systemui会接收该广播,显示耳机插入图标。当然可以继续往下跟。直到sendbroadcast。            sendDeviceConnectionIntent(device, state, address, deviceName, shouldNotify);        }    }}

问题来了,framework这边是监听UEvent事件。那么kernel那边是怎么传递UEvent事件的?何时写那个event节点?
在kernel下面的Accdet.c和Switch_class.c文件中,但是看不懂。下面看下正常的log信息。(一次插拔)

上层log:    main.log:        Line 4700: 01-01 01:59:42.575111   297   655 D AudioHeadSetMessager: /sys/class/switch/h2w/state => 0        //这个是上层打印节点信息,为0表示没插耳机。但是这个信息并不是实时的,有触发条件才打印这个信息。        Line 5349: 01-01 01:59:46.025161   750  1746 I WiredAccessoryManager: MSG_NEW_DEVICE_STATE        Line 5350: 01-01 01:59:46.027819   750   750 D WiredAccessoryManager: WiredHeadset num_hs_pole is num_hs_pole=4 //耳机插入后,设置音频回路        Line 5483: 01-01 01:59:46.252001   297   655 D AudioHeadSetMessager: /sys/class/switch/h2w/state => 1        Line 6656: 01-01 01:59:51.816985   750  1746 I WiredAccessoryManager: MSG_NEW_DEVICE_STATE        Line 6657: 01-01 01:59:51.823965   750   750 D WiredAccessoryManager: WiredHeadset num_hs_pole is NA //耳机拔出。    sys.log:(UEVENT事件)        Line 1945: 01-01 01:59:46.023538   750  1746 V WiredAccessoryManager: Headset UEVENT: {SUBSYSTEM=switch, SEQNUM=2534, ACTION=change, SWITCH_STATE=1,     SWITCH_NAME=h2w, DEVPATH=/devices/virtual/switch/h2w}        Line 2054: 01-01 01:59:51.784900   750  1746 V WiredAccessoryManager: Headset UEVENT: {SUBSYSTEM=switch, SEQNUM=2535, ACTION=change, SWITCH_STATE=0,     SWITCH_NAME=h2w, DEVPATH=/devices/virtual/switch/h2w}kernel.log:    Line 3391: 01-01 01:59:45.967827   112   112 D [ 7379.926647]-(0)[112:display_idle_de][name:accdet&]: [Accdet]Enter accdet_eint_func !!!!!!    Line 3391: 01-01 01:59:45.967827   112   112 D [ 7379.926647]-(0)[112:display_idle_de][name:accdet&]: [Accdet]Enter accdet_eint_func !!!!!!    Line 3391: 01-01 01:59:45.967827   112   112 D [ 7379.926647]-(0)[112:display_idle_de][name:accdet&]: [Accdet]Enter accdet_eint_func !!!!!!    Line 3394: 01-01 01:59:45.968990   112   112 D [ 7379.927810]-(0)[112:display_idle_de][name:accdet&]: [Accdet]accdet_eint_func after cur_eint_state=1  //当前耳机状态    Line 3394: 01-01 01:59:45.968990   112   112 D [ 7379.927810]-(0)[112:display_idle_de][name:accdet&]: [Accdet]accdet_eint_func after cur_eint_state=1    Line 3394: 01-01 01:59:45.968990   112   112 D [ 7379.927810]-(0)[112:display_idle_de][name:accdet&]: [Accdet]accdet_eint_func after cur_eint_state=1    Line 3395: 01-01 01:59:45.970231  3765  3765 D [ 7379.929051] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]ACC EINT func :plug-in, cur_eint_state = 1    Line 3395: 01-01 01:59:45.970231  3765  3765 D [ 7379.929051] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]ACC EINT func :plug-in, cur_eint_state = 1    Line 3396: 01-01 01:59:45.970296  3765  3765 D [ 7379.929116] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]accdet hardware init    Line 3396: 01-01 01:59:45.970296  3765  3765 D [ 7379.929116] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]accdet hardware init    Line 3396: 01-01 01:59:45.970296  3765  3765 D [ 7379.929116] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]accdet hardware init    Line 3397: 01-01 01:59:45.970553  3765  3765 D [ 7379.929373] (0)[3765:kworker/u8:3][name:accdet&]: accdet: enable_accdet    Line 3397: 01-01 01:59:45.970553  3765  3765 D [ 7379.929373] (0)[3765:kworker/u8:3][name:accdet&]: accdet: enable_accdet    Line 3397: 01-01 01:59:45.970553  3765  3765 D [ 7379.929373] (0)[3765:kworker/u8:3][name:accdet&]: accdet: enable_accdet    Line 3398: 01-01 01:59:45.970642  3765  3765 D [ 7379.929462] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]enable_irq  !!!!!!    Line 3398: 01-01 01:59:45.970642  3765  3765 D [ 7379.929462] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]enable_irq  !!!!!!   //耳机插入使能中断,下面中断处理    Line 3408: 01-01 01:59:46.076401    54    54 D [ 7380.035221] (0)[54:pmic_thread][name:accdet&]: [accdet_int_handler]....    Line 3408: 01-01 01:59:46.076401    54    54 D [ 7380.035221] (0)[54:pmic_thread][name:accdet&]: [accdet_int_handler]....    Line 3409: 01-01 01:59:46.076448    54    54 D [ 7380.035268] (0)[54:pmic_thread][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x101    Line 3409: 01-01 01:59:46.076448    54    54 D [ 7380.035268] (0)[54:pmic_thread][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x101    Line 3409: 01-01 01:59:46.076448    54    54 D [ 7380.035268] (0)[54:pmic_thread][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x101    Line 3409: 01-01 01:59:46.076448    54    54 D [ 7380.035268] (0)[54:pmic_thread][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x101    Line 3411: 01-01 01:59:46.077660  3765  3765 D [ 7380.036480] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]accdet interrupt happen:[Plug_out]current AB = 1    Line 3411: 01-01 01:59:46.077660  3765  3765 D [ 7380.036480] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]accdet interrupt happen:[Plug_out]current AB = 1    Line 3411: 01-01 01:59:46.077660  3765  3765 D [ 7380.036480] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]accdet interrupt happen:[Plug_out]current AB = 1    Line 3412: 01-01 01:59:46.077717  3765  3765 D [ 7380.036537] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]check_cable_type:Clear interrupt:Done[0x0]!    Line 3412: 01-01 01:59:46.077717  3765  3765 D [ 7380.036537] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]check_cable_type:Clear interrupt:Done[0x0]!    Line 3413: 01-01 01:59:46.077736  3765  3765 D [ 7380.036556] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]cable type:[Headset_mic], status switch:[Plug_out]->[Headset_plug_in]    Line 3413: 01-01 01:59:46.077736  3765  3765 D [ 7380.036556] (0)[3765:kworker/u8:3][name:accdet&]: [Accdet]cable type:[Headset_mic], status switch:[Plug_out]->[Headset_plug_in]    Line 3414: 01-01 01:59:46.078033  3765  3765 D [ 7380.036853] (0)[3765:kworker/u8:3][name:accdet&]: [accdet] set state in cable_type  status    Line 3414: 01-01 01:59:46.078033  3765  3765 D [ 7380.036853] (0)[3765:kworker/u8:3][name:accdet&]: [accdet] set state in cable_type  status     //kernel 处理耳机插入完毕    Line 3816: 01-01 01:59:51.835056     0     0 D [ 7385.793876]-(0)[0:swapper/0][name:accdet&]: [Accdet]Enter accdet_eint_func !!!!!!    Line 3816: 01-01 01:59:51.835056     0     0 D [ 7385.793876]-(0)[0:swapper/0][name:accdet&]: [Accdet]Enter accdet_eint_func !!!!!!    Line 3816: 01-01 01:59:51.835056     0     0 D [ 7385.793876]-(0)[0:swapper/0][name:accdet&]: [Accdet]Enter accdet_eint_func !!!!!!    Line 3819: 01-01 01:59:51.836283     0     0 D [ 7385.795103]-(0)[0:swapper/0][name:accdet&]: [Accdet]accdet_eint_func after cur_eint_state=0  //耳机拔出了    Line 3819: 01-01 01:59:51.836283     0     0 D [ 7385.795103]-(0)[0:swapper/0][name:accdet&]: [Accdet]accdet_eint_func after cur_eint_state=0    Line 3819: 01-01 01:59:51.836283     0     0 D [ 7385.795103]-(0)[0:swapper/0][name:accdet&]: [Accdet]accdet_eint_func after cur_eint_state=0    Line 3820: 01-01 01:59:51.837338  3764  3764 D [ 7385.796158] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]ACC EINT func :plug-out, cur_eint_state = 0    Line 3820: 01-01 01:59:51.837338  3764  3764 D [ 7385.796158] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]ACC EINT func :plug-out, cur_eint_state = 0    Line 3821: 01-01 01:59:51.837481  3764  3764 D [ 7385.796301] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x100    Line 3821: 01-01 01:59:51.837481  3764  3764 D [ 7385.796301] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x100    Line 3821: 01-01 01:59:51.837481  3764  3764 D [ 7385.796301] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x100    Line 3821: 01-01 01:59:51.837481  3764  3764 D [ 7385.796301] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x100    Line 3822: 01-01 01:59:51.837792  3764  3764 D [ 7385.796612] (0)[3764:kworker/u8:2][name:accdet&]: accdet: disable_accdet    Line 3822: 01-01 01:59:51.837792  3764  3764 D [ 7385.796612] (0)[3764:kworker/u8:2][name:accdet&]: accdet: disable_accdet    Line 3822: 01-01 01:59:51.837792  3764  3764 D [ 7385.796612] (0)[3764:kworker/u8:2][name:accdet&]: accdet: disable_accdet    Line 3827: 01-01 01:59:51.868291  3764  3764 D [ 7385.827111] (0)[3764:kworker/u8:2][name:accdet&]: [accdet] set state in cable_type = NO_DEVICE   //耳机拔出了    Line 3827: 01-01 01:59:51.868291  3764  3764 D [ 7385.827111] (0)[3764:kworker/u8:2][name:accdet&]: [accdet] set state in cable_type = NO_DEVICE    Line 3828: 01-01 01:59:51.868316  3764  3764 D [ 7385.827136] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]enable_irq  !!!!!!    Line 3828: 01-01 01:59:51.868316  3764  3764 D [ 7385.827136] (0)[3764:kworker/u8:2][name:accdet&]: [Accdet]enable_irq  !!!!!!
原创粉丝点击