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交互的这段边界部分。
...mUEventObserver.startObserving(USB_STATE_MATCH); mUEventObserver.startObserving();...
下面我们转到UEventObserver中,UEventObserver 是一个Interface,定义了一个回调方法,onUEvent,通过它将kernal 上报事件传递至app/framework层、
private final UEventObserver mUEventObserver = new UEventObserver() {@Overridepublic void onUEvent(UEventObserver.UEvent event) { String state = event.get("USB_STATE");String accessory = event.get("ACCESSORY");if (state != null) {mHandler.updateState(state); } 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) {...final UEventThread t = getThread();t.addObserver(match, this); }
接下来,startObserving方法转到了UEventThread中。UEventThread是个线程是UEventObserver的内部类,run方法中是个死循环,不断地监听UEvent,当有事件从Kernal上报时,则通过Handler一步步上传。UEventThread 在UEventObserver中以单例模式存在。
private static UEventThread getThread() {synchronized (UEventObserver.class) { if (sThread == null) {sThread = new UEventThread(); sThread.start();}return sThread;}}
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");}@Overridepublic void run() {nativeSetup();while (true) {
String message = nativeWaitForNextEvent();if (message != null) {sendEvent(message);}}}
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); if (message.contains(key)) {final UEventObserver observer =(UEventObserver)mKeysAndObservers.get(i + 1); mTempObserversToSignal.add(observer);}}}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();}}public void addObserver(String match, UEventObserver observer) {synchronized (mKeysAndObservers) {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)) {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
- UsbInterface,UsbConfigration,UsbDevice 的创建
- USB相关Notification的显示流程,源码解析
从上面的分析我们看到,当有新的UEvent从kernal 过来后,UEventObserver回调在UsbDeviceManager中,此时我们通过Handler消息机制,更新Notification的显示。具体过程如下:
private final UEventObserver mUEventObserver = new UEventObserver() {@Overridepublic void onUEvent(UEventObserver.UEvent event) { 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); Message msg = Message.obtain(this, MSG_UPDATE_STATE);msg.arg1 = connected;msg.arg2 = configured;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 的处理是关键。
@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_UPDATE_STATE:mConnected = (msg.arg1 == 1); mConfigured = (msg.arg2 == 1);updateUsbNotification(); updateAdbNotification();if (containsFunction(mCurrentFunctions,UsbManager.USB_FUNCTION_ACCESSORY)) {updateCurrentAccessory();} else if (!mConnected) {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; } 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; } else {}}if (id != mUsbNotificationId) {if (mUsbNotificationId != 0) { mNotificationManager.cancelAsUser(null,mUsbNotificationId,UserHandle.ALL);mUsbNotificationId = 0;}if (id != 0) {CharSequence message = r.getText(com.android.internal.R.string.usb_notification_message); 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; 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的更新就先讲到这里了