SystemUI之USB1(kernel->Framework UEvent)

kernel那边有USB事件后,往上层传到framework,封装消息后通知systemUI。


第一节 
Kernal 与 Framework层交互 UEventObserver;插入与拔出USB设备,事件监听以及上报.UEventObserver

涉及到的类文件: 
- android_os_UEventObserver.cpp 
./frameworks/base/core/jni/android_os_UEventObserver.cpp 
- UEventObserver.Java 
./frameworks/base/core/java/Android/os/UEventObserver.java

插拔U盘,usb事件上报 
在UsbDeviceManager.java的构造方法中,添加了USB_STATE_MATCH和ACCESSORY_START_MATCH监听。因此,下面我们就按照源码跟踪framework与kernal交互的这段边界部分。    

    ...
    // Watch for USB configuration changes
    mUEventObserver.startObserving(USB_STATE_MATCH);    
    mUEventObserver.startObserving();
    ...
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

下面我们转到UEventObserver中,UEventObserver 是一个Interface,定义了一个回调方法,onUEvent,通过它将kernal 上报事件传递至app/framework层、

/*mUEventObserver的声明:
     * Listens for uevent messages from the kernel to monitor the USB state
     */
    private final UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) { //这里从UEventThead
            String state = event.get("USB_STATE");
            String accessory = event.get("ACCESSORY");
            if (state != null) {
                mHandler.updateState(state); //更新USB当前的状态,CONNECTED ,DISCONNECTED,CONFIGURED
            } else if ...
        }
    };
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

先看UEventObserver中的startObservering方法

    public final void startObserving(String match) {
        ...
        //The UEventThread is Singleton pattern.
        final UEventThread t = getThread();
        t.addObserver(match, this); //this参数,当onUEvent回调时,则回调到注册的这个Observer中。

    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

接下来,startObserving方法转到了UEventThread中。UEventThread是个线程是UEventObserver的内部类,run方法中是个死循环,不断地监听UEvent,当有事件从Kernal上报时,则通过Handler一步步上传。UEventThread 在UEventObserver中以单例模式存在。

//Create the thread and start it
    private static UEventThread getThread() {
        synchronized (UEventObserver.class) { //keep it sysncronized
            if (sThread == null) {
                sThread = new UEventThread(); //第一次创建并start
                sThread.start();
            }
            return sThread;
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

UEventThread:

 private static final class UEventThread extends Thread {
        /** Many to many mapping of string match to observer.
         *  Multimap would be better, but not available in android, so use
         *  an ArrayList where even elements are the String match and odd
         *  elements the corresponding(相关的) UEventObserver observer */
        private final ArrayList<Object> mKeysAndObservers = new ArrayList<Object>();
        private final ArrayList<UEventObserver> mTempObserversToSignal =
                new ArrayList<UEventObserver>();
        public UEventThread() {
            super("UEventObserver");
        }
        @Override
        public void run() {
            nativeSetup();
            while (true) {//   a loop to get Event everytime
             String message = nativeWaitForNextEvent();//wait for the next Event
                if (message != null) {
                    sendEvent(message);
                }
            }
        }
//向上层发送Event
        private void sendEvent(String message) {
            synchronized (mKeysAndObservers) {
                final int N = mKeysAndObservers.size();
                for (int i = 0; i < N; i += 2) {
                    final String key = (String)mKeysAndObservers.get(i); // the match String index is i
                    //遍历list中所有的match String
                    if (message.contains(key)) {
                        final UEventObserver observer =
                                (UEventObserver)mKeysAndObservers.get(i + 1); // then , the Observer object in ArrayList index is (i+1)
                        mTempObserversToSignal.add(observer);
                    }
                }
            }

            if (!mTempObserversToSignal.isEmpty()) {
                final UEvent event = new UEvent(message);
                //mTempObserversToSignal存储是的与该message相配套的Observer,所以这里遍历后,将message全部发出去。
                final int N = mTempObserversToSignal.size();
                for (int i = 0; i < N; i++) {
                    final UEventObserver observer = mTempObserversToSignal.get(i);
                    observer.onUEvent(event); //找到与回调回去了
                }
                //发出去完了,等待下一波
                mTempObserversToSignal.clear();
            }
        }
        // “matchA”,ObserverA ;"matchB",ObserverB ...
        // 这里的match String 和 Observer Object是成双成对的,如果我取到了match String index 为 i,则Observer object 的index 为 (i+1)
        // 这里 match是不会一致的,否则就重复了,但是Observer 是会有可能同一个
        public void addObserver(String match, UEventObserver observer) {
            synchronized (mKeysAndObservers) {
                //mKeyAndroidObservers key to value
                mKeysAndObservers.add(match); 
                mKeysAndObservers.add(observer);
                nativeAddMatch(match);
            }
        }
                ...
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

在UEventThread中,有两个ArrayList,一个是mKeysAndObservers,虽然是个List但是它扮演的是Map的角色,里面的match (String) , Observer(Object) 一一对应,这里就有疑问了?为何不直接使用map呢?map不正好是key-value对应的吗? 我的认为是,list里面match (String) 与Obsever的对应是存在重复的情况。但是map中是不允许key重复的。这应该是没有使用Map的原因吧。?????

另外一个是mTempObserversToSignal ,作为临时变量。framework/base/core/jni/android_os_UEventObserver.cpp 

那UEvent从哪里来呢?从nativeWaitForNextEvent这里来。后面的部分暂时不继续往下跟了。

static jstring nativeWaitForNextEvent(JNIEnv *env, jclass clazz) {
    char buffer[1024];
    for (;;) {
        int length = uevent_next_event(buffer, sizeof(buffer) - 1);
        if (length <= 0) {
            return NULL;
        }
        buffer[length] = '\0';
        ALOGV("Received uevent message: %s", buffer);
        if (isMatch(buffer, length)) {
            // Assume the message is ASCII.
            jchar message[length];
            for (int i = 0; i < length; i++) {
                message[i] = buffer[i];
            }
            return env->NewString(message, length);
        }
    }}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  1. UsbInterface,UsbConfigration,UsbDevice 的创建
  2. USB相关Notification的显示流程,源码解析

从上面的分析我们看到,当有新的UEvent从kernal 过来后,UEventObserver回调在UsbDeviceManager中,此时我们通过Handler消息机制,更新Notification的显示。具体过程如下:

 private final UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) { //这里从UEventThead
            if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString());
            String state = event.get("USB_STATE");
            String accessory = event.get("ACCESSORY");
            if (state != null) {
                mHandler.updateState(state);
            } else if {...}
        }
    };
mHandler中的updateState:
       public void updateState(String state) {
            int connected, configured;
            if ("DISCONNECTED".equals(state)) {  //断开连接
                connected = 0;
                configured = 0;
            } else if ("CONNECTED".equals(state)) {  //连接上
                connected = 1;
                configured = 0;
            } else if ("CONFIGURED".equals(state)) {
                connected = 1;
                configured = 1;
            } else {
                Slog.e(TAG, "unknown state " + state);
                return;
            }
            removeMessages(MSG_UPDATE_STATE); //avoid MSG repeated
            Message msg = Message.obtain(this, MSG_UPDATE_STATE);
            msg.arg1 = connected;
            msg.arg2 = configured;
            // debounce disconnects to avoid problems bringing up USB tethering
            sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
        }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

此处对MSG_UPDATE_STATE 的处理是关键。

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_STATE:
                    mConnected = (msg.arg1 == 1); 
                    mConfigured = (msg.arg2 == 1);
                    updateUsbNotification(); // 更新USB Notification
                    updateAdbNotification();
                    if (containsFunction(mCurrentFunctions,
                            UsbManager.USB_FUNCTION_ACCESSORY)) {
                        updateCurrentAccessory();
                    } else if (!mConnected) {
                        // restore defaults when USB is disconnected
                        setEnabledFunctions(getDefaultFunctions(), false);
                    }
                    if (mSystemReady) {
                        updateUsbState();
                        updateAudioSourceFunction();
                    }
                    break;
                    ...
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

接下来我们只看updateUsbNotification方法。这个方法很简单,就是更新Notification,就是我们平时插上USB连接线的时候,顶部通知栏会显示的通知。

如果你要添加声音或者振动,或者更改图标等,算是找对地方了。

  private void updateUsbNotification() {
            if (mNotificationManager == null || !mUseUsbNotification) return;
            int id = 0;
            Resources r = mContext.getResources();
            if (mConnected) {
                if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) {
                    id = com.android.internal.R.string.usb_mtp_notification_title; //作为USB设备链接
                } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) {
                    id = com.android.internal.R.string.usb_ptp_notification_title;//作为相机链接
                } else if (containsFunction(mCurrentFunctions,
                        UsbManager.USB_FUNCTION_MASS_STORAGE)) {
                    id = com.android.internal.R.string.usb_cd_installer_notification_title; //作为安装应用程序
                } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) {
                    id = com.android.internal.R.string.usb_accessory_notification_title; // 已链接到USB配件
                } else {
                    // There is a different notification for USB tethering so we don't need one here
                    //if (!containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) {
                    //    Slog.e(TAG, "No known USB function in updateUsbNotification");
                    //}
                }
            }
            if (id != mUsbNotificationId) {
                // clear notification if title needs changing
                if (mUsbNotificationId != 0) { //当前正在显示的notification id
                    mNotificationManager.cancelAsUser(null,mUsbNotificationId,UserHandle.ALL);
                    mUsbNotificationId = 0;
                }
                if (id != 0) {
                    CharSequence message = r.getText(
                            com.android.internal.R.string.usb_notification_message); //触摸可以显示其他USB选项
                    CharSequence title = r.getText(id);

                    Notification notification = new Notification();
                    notification.icon = com.android.internal.R.drawable.stat_sys_data_usb;
                    notification.when = 0; 
                    notification.flags = Notification.FLAG_ONGOING_EVENT;
                    notification.tickerText = title;
                    //如果我们需要添加声音,是否振动或者更改显示的图标,可以修改这里。
                    notification.defaults = 0; // please be quiet
                    notification.sound = null;
                    notification.vibrate = null;
                    //设置优先级
                    notification.priority = Notification.PRIORITY_MIN;

                    //点击通知栏后的操作
                    Intent intent = Intent.makeRestartActivityTask(
                            new ComponentName("com.android.settings",
                                    "com.android.settings.UsbSettings"));
                    PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                            intent, 0, null, UserHandle.CURRENT);
                    notification.color = mContext.getResources().getColor(
                            com.android.internal.R.color.system_notification_accent_color);
                    notification.setLatestEventInfo(mContext, title, message, pi);
                    notification.visibility = Notification.VISIBILITY_PUBLIC;
                    mNotificationManager.notifyAsUser(null, id, notification,
                            UserHandle.ALL);
                    mUsbNotificationId = id;
                }
            }
        }
        ......
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

Kernal —> Framework UEvent这部分,并插拔USB时,Notification的更新就先讲到这里了





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值