Android N 插拔USB行为分析
2018-01-20 10:11
441 查看
在Anrdoid L的版本上,如果用户USB连接PC设备后,选择MTP模式,然后移除连接,再次重新连接之后,设备还是以MTP模式连接的。而在Android N上,如果用户按照相同的操作,设备却是以充电模式连接的,这是为什么呢?如果更改才能回到以前的逻辑呢?
首先UsbDeviceManager中注册了UEvent接收内核中USB拔插的消息,收到消息后会调用mHandler.updateState(state);
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;
// debounce disconnects to avoid problems bringing up USB tethering
sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
}
case MSG_UPDATE_STATE:
mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1);
if (!mConnected) {
// When a disconnect occurs, relock access to sensitive user data
mUsbDataUnlocked = false;
}
updateUsbNotification();
updateAdbNotification();
if (UsbManager.containsFunction(mCurrentFunctions,
UsbManager.USB_FUNCTION_ACCESSORY)) {
updateCurrentAccessory();
} else if (!mConnected) {
// restore defaults when USB is disconnected
setEnabledFunctions(null, false);//设置usb功能为空,也就是充电模式
}
if (mBootCompleted) {
updateUsbStateBroadcastIfNeeded();
updateUsbFunctions();
}
break; 可以看出当拔出USB时,会更新mConnected的值,最终如果值为false的话会调用
setEnabledFunctions(null, false);//设置usb功能为空,也就是充电模式 那要想改这块的逻辑,是不是把这段代码注释了就可以了?我试了,是不行的,虽然persist.sys.usb.config和sys.usb.config的值是mtp,adb,但是实际mtp功能是不能用的,到底为什么呢?答案在下面的代码:
if (!mConnected) {
// When a disconnect occurs, relock access to sensitive user data
mUsbDataUnlocked = false;
}
private static final String USB_STATE_MATCH = "DEVPATH=/devices/virtual/android_usb/android0"; private final UEventObserver mUEventObserver = new UEventObserver() { @Override public 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 ("START".equals(accessory)) { if (DEBUG) Slog.d(TAG, "got accessory start"); startAccessoryMode(); } } };
mUEventObserver.startObserving(USB_STATE_MATCH);
首先UsbDeviceManager中注册了UEvent接收内核中USB拔插的消息,收到消息后会调用mHandler.updateState(state);
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;
// debounce disconnects to avoid problems bringing up USB tethering
sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
}
case MSG_UPDATE_STATE:
mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1);
if (!mConnected) {
// When a disconnect occurs, relock access to sensitive user data
mUsbDataUnlocked = false;
}
updateUsbNotification();
updateAdbNotification();
if (UsbManager.containsFunction(mCurrentFunctions,
UsbManager.USB_FUNCTION_ACCESSORY)) {
updateCurrentAccessory();
} else if (!mConnected) {
// restore defaults when USB is disconnected
setEnabledFunctions(null, false);//设置usb功能为空,也就是充电模式
}
if (mBootCompleted) {
updateUsbStateBroadcastIfNeeded();
updateUsbFunctions();
}
break; 可以看出当拔出USB时,会更新mConnected的值,最终如果值为false的话会调用
setEnabledFunctions(null, false);//设置usb功能为空,也就是充电模式 那要想改这块的逻辑,是不是把这段代码注释了就可以了?我试了,是不行的,虽然persist.sys.usb.config和sys.usb.config的值是mtp,adb,但是实际mtp功能是不能用的,到底为什么呢?答案在下面的代码:
if (!mConnected) {
// When a disconnect occurs, relock access to sensitive user data
mUsbDataUnlocked = false;
}
private void updateUsbStateBroadcastIfNeeded() { // send a sticky broadcast containing current USB state Intent intent = new Intent(UsbManager.ACTION_USB_STATE); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(UsbManager.USB_CONNECTED, mConnected); intent.putExtra(UsbManager.USB_HOST_CONNECTED, mHostConnected); intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);//奥秘就在这里 if (mCurrentFunctions != null) { String[] functions = mCurrentFunctions.split(","); for (int i = 0; i < functions.length; i++) { final String function = functions[i]; if (UsbManager.USB_FUNCTION_NONE.equals(function)) { continue; } intent.putExtra(function, true); } } // send broadcast intent only if the USB state has changed if (!isUsbStateChanged(intent)) { if (DEBUG) { Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras()); } return; } if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras()); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); mBroadcastedIntent = intent; }
intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);//奥秘就在这里把这段代码里面的mUsbDataUnlocked改为true就可以达到Android L的效果。具体为什么,我没有去看。
相关文章推荐
- android 4.0.3 usb插拔提示音播放问题分析
- android 4.0.3 usb插拔提示音播放问题分析
- Anubis,一个支持Android apk(Android binaries)行为分析的在线沙盘
- android usb挂载分析---MountService启动
- android之通过USB插拔流程来了解android UEvent
- android usb挂载分析---vold处理FrameWork层发出的消息
- android usb挂载分析----vold启动
- Android的BroadcastReciver,增加 addDataScheme("file") 才能收到SD卡插拔事件的原因分析 -- 浅析android事件过滤策略
- 【BroadcastReceiver】增加 addDataScheme("file") 才能收到SD卡插拔事件的原因分析 -- 浅析android事件过滤策略
- 运用smali自动注入技术分析android应用程序行为
- 分析android的usb-gadget
- 百度贴吧客户端(Android)网络通信行为分析
- android usb挂载分析---MountService启动
- 运用smali自动注入技术分析android应用程序行为
- android usb挂载分析---MountService启动
- android USB gadget框架分析
- Android 行为分析—GA用户行为分析
- 增加 addDataScheme("file") 才能收到SD卡插拔事件的原因分析 -- 浅析android事件过滤策略
- 分析android的usb-gadget
- Android USB 驱动分析与开发----编程