Android 允许USB调试弹窗是怎么弹出来的

您所在的位置:网站首页 usb调试是什么意思怎么打开 Android 允许USB调试弹窗是怎么弹出来的

Android 允许USB调试弹窗是怎么弹出来的

2023-07-29 05:42| 来源: 网络整理| 查看: 265

通过 adb 调试直接安装应用到真机上,简单方便。

adb connect 192.168.1.1 adb connect 192.168.1.1:5555 //指定端口为 5555

在 AN 8.0 上,用上述命令adb调试真机时,首次连接会出现 “允许USB调试吗” 的弹窗,这个弹窗怎么出来的,源码一探究竟。 在这里插入图片描述 在串口调试工具敲命令 dumpsys activity activities | grep mResumedActivity 得知, 这个页面是 com.android.systemui/.usb.UsbDebuggingActivity , 源码路径

frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java

关注 onClick 方法,调用了 IUsbManager 的 allowUsbDebugging 方法。

@Override public void onClick(DialogInterface dialog, int which) { boolean allow = (which == AlertDialog.BUTTON_POSITIVE); boolean alwaysAllow = allow && mAlwaysAllow.isChecked(); try { IBinder b = ServiceManager.getService(USB_SERVICE); IUsbManager service = IUsbManager.Stub.asInterface(b); if (allow) { service.allowUsbDebugging(alwaysAllow, mKey); } else { service.denyUsbDebugging(); } } catch (Exception e) { Log.e(TAG, "Unable to notify Usb service", e); } finish(); }

相关联的文件为:

frameworks/base/services/usb/java/com/android/server/usb/UsbService.java frameworks/base/core/java/android/hardware/usb/IUsbManager.aidl frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java frameworks/base/services/usb/java/com/android/server/usb/UsbDebuggingManager.java

1 查看 UsbService.java ,实际调用的是 UsbDeviceManager.allowUsbDebugging(alwaysAllow, publicKey) ;

private UsbDeviceManager mDeviceManager; @Override public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey); }

2 查看 frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java ,实际调用 UsbDebuggingManager.allowUsbDebugging(boolean alwaysAllow, String publicKey) ;

private UsbDebuggingManager mDebuggingManager; public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { if (mDebuggingManager != null) { mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey); } }

3 查看 frameworks/base/services/usb/java/com/android/server/usb/UsbDebuggingManager.java ,发出了 MESSAGE_ADB_ALLOW 消息;

public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_ALLOW); msg.arg1 = alwaysAllow ? 1 : 0; msg.obj = publicKey; mHandler.sendMessage(msg); }

UsbDebuggingHandler 内容如下,启动了 UsbDebuggingThread 以及 Handler 收发消息流程。

class UsbDebuggingHandler extends Handler { private static final int MESSAGE_ADB_ENABLED = 1; private static final int MESSAGE_ADB_DISABLED = 2; private static final int MESSAGE_ADB_ALLOW = 3; private static final int MESSAGE_ADB_DENY = 4; private static final int MESSAGE_ADB_CONFIRM = 5; private static final int MESSAGE_ADB_CLEAR = 6; public UsbDebuggingHandler(Looper looper) { super(looper); } public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_ADB_ENABLED: if (mAdbEnabled) break; mAdbEnabled = true; mThread = new UsbDebuggingThread(); mThread.start(); break; case MESSAGE_ADB_DISABLED: if (!mAdbEnabled) break; mAdbEnabled = false; if (mThread != null) { mThread.stopListening(); mThread = null; } break; case MESSAGE_ADB_ALLOW: { String key = (String)msg.obj; String fingerprints = getFingerprints(key); if (!fingerprints.equals(mFingerprints)) { Slog.e(TAG, "Fingerprints do not match. Got " + fingerprints + ", expected " + mFingerprints); break; } if (msg.arg1 == 1) { writeKey(key); } if (mThread != null) { mThread.sendResponse("OK"); } break; } case MESSAGE_ADB_DENY: if (mThread != null) { mThread.sendResponse("NO"); } break; case MESSAGE_ADB_CONFIRM: { if ("trigger_restart_min_framework".equals( SystemProperties.get("vold.decrypt"))) { Slog.d(TAG, "Deferring adb confirmation until after vold decrypt"); if (mThread != null) { mThread.sendResponse("NO"); } break; } String key = (String)msg.obj; String fingerprints = getFingerprints(key); if ("".equals(fingerprints)) { if (mThread != null) { mThread.sendResponse("NO"); } break; } mFingerprints = fingerprints; startConfirmation(key, mFingerprints); break; } case MESSAGE_ADB_CLEAR: deleteKeyFile(); break; } } }

其中 if (msg.arg1 == 1) { writeKey(key); } 就是如果勾选了 “一律允许这台计算机进行调试” ,则将对应的 key 保存到 data/misc/adb/adb_keys 文件里。

说到这里,弹窗的逻辑实现就知道了。 不对啊,还是没说弹窗怎么出来的。别急,继续。

将 UsbDebuggingManager.java 的 log 开关打开,

- private static final boolean DEBUG = false; + private static final boolean DEBUG = true;

首次执行 adb connect 会出现如下 log :

07-06 16:34:58.167 1570 2615 D UsbDebuggingManager: Received public key: QAAAAGkQ5x8ngNhLRdKw3vO6i8jRUZeQzah1weiQuMq1z1sjaB8Otto2ISD66X+sxmjxIj4CpTqIlGJxsfmn74yylU0menZepnLE4031e5E4sOT/07MAW+JtVipMTS1JareqAv5PCVof1tTzS5iy2L4iudG7POBMki39r4OCUKmpOlmMdZQBhR1ADpcK/rystSgJm9mpbWv38UN4KcNS+x5w0sKx/bNp3yJ/oY1hLWnWbHJDL0KMVChr7+Fb7hc9VwOUS5G4V1YkNaa7LTM7PHGN6WknevqIp2SxCvkE5J6/1FbtBWk/HGrf3fuPKoQEQmKQdVzm+ysN0ErZ1L6JnKu6mtZofb6wVEAODhVMWrWY3YhFt/IHucDTWkCByXcmERmHpkcLtGk6w8nq+6COpfFkRoX2ZP4IZUyn8aqI5Mm4xf95RwK6vVwNhFsYzp8RctD2qVWq5nL5iCwqp9n2i4etShmjNH/VFIpaoP/H5YXP8bMBnYjPfTU9kUYn0kpRgHHQ8kkiXrLJ5XFwrKFAv0pSK9W0kDJFsaRvkLb2H3EebqJnZdWEeTq0haBAMjoesbUI0lmxtJ9zaE5rsbh/NWXs/SlFHMvY3wH99b7ZH8UqBc4bJGDQd4oi8gKeXHLh574EmGf9G6/I+eV2zKgknL+RJtnhyc8FvS+SV8Suh9o5PjF6OVA4pwEAAQA= @unknown

依据 Received public key 关键字找到 UsbDebuggingManager --> UsbDebuggingThread

class UsbDebuggingThread extends Thread { private boolean mStopped; private LocalSocket mSocket; private OutputStream mOutputStream; private InputStream mInputStream; UsbDebuggingThread() { super(TAG); } @Override public void run() { if (DEBUG) Slog.d(TAG, "Entering thread"); while (true) { synchronized (this) { if (mStopped) { if (DEBUG) Slog.d(TAG, "Exiting thread"); return; } try { openSocketLocked(); } catch (Exception e) { /* Don't loop too fast if adbd dies, before init restarts it */ SystemClock.sleep(1000); } } try { listenToSocket(); } catch (Exception e) { /* Don't loop too fast if adbd dies, before init restarts it */ SystemClock.sleep(1000); } } } private void openSocketLocked() throws IOException { try { LocalSocketAddress address = new LocalSocketAddress(ADBD_SOCKET, LocalSocketAddress.Namespace.RESERVED); mInputStream = null; if (DEBUG) Slog.d(TAG, "Creating socket"); mSocket = new LocalSocket(); mSocket.connect(address); mOutputStream = mSocket.getOutputStream(); mInputStream = mSocket.getInputStream(); } catch (IOException ioe) { closeSocketLocked(); throw ioe; } } private void listenToSocket() throws IOException { try { byte[] buffer = new byte[BUFFER_SIZE]; while (true) { int count = mInputStream.read(buffer); if (count < 0) { break; } if (buffer[0] == 'P' && buffer[1] == 'K') { String key = new String(Arrays.copyOfRange(buffer, 2, count)); Slog.d(TAG, "Received public key: " + key); Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_CONFIRM); msg.obj = key; mHandler.sendMessage(msg); } else { Slog.e(TAG, "Wrong message: " + (new String(Arrays.copyOfRange(buffer, 0, 2)))); break; } } } finally { synchronized (this) { closeSocketLocked(); } } } private void closeSocketLocked() { if (DEBUG) Slog.d(TAG, "Closing socket"); try { if (mOutputStream != null) { mOutputStream.close(); mOutputStream = null; } } catch (IOException e) { Slog.e(TAG, "Failed closing output stream: " + e); } try { if (mSocket != null) { mSocket.close(); mSocket = null; } } catch (IOException ex) { Slog.e(TAG, "Failed closing socket: " + ex); } } /** Call to stop listening on the socket and exit the thread. */ void stopListening() { synchronized (this) { mStopped = true; closeSocketLocked(); } } void sendResponse(String msg) { synchronized (this) { if (!mStopped && mOutputStream != null) { try { mOutputStream.write(msg.getBytes()); } catch (IOException ex) { Slog.e(TAG, "Failed to write response:", ex); } } } } }

代码流程为 UsbDebuggingThread 通过 openSocketLocked() 开启 Socket 连接并且监听 listenToSocket(), 收到 adb connect 消息后,发出 msg UsbDebuggingHandler.MESSAGE_ADB_CONFIRM , 查看 UsbDebuggingHandler 可知,调用了 startConfirmation(key, mFingerprints);

private void startConfirmation(String key, String fingerprints) { int currentUserId = ActivityManager.getCurrentUser(); UserHandle userHandle = UserManager.get(mContext).getUserInfo(currentUserId).getUserHandle(); String componentString; if (currentUserId == UserHandle.USER_OWNER) { componentString = Resources.getSystem().getString( com.android.internal.R.string.config_customAdbPublicKeyConfirmationComponent); } else { // If the current foreground user is not the primary user we send a different // notification specific to secondary users. componentString = Resources.getSystem().getString( R.string.config_customAdbPublicKeyConfirmationSecondaryUserComponent); } ComponentName componentName = ComponentName.unflattenFromString(componentString); if (startConfirmationActivity(componentName, userHandle, key, fingerprints) || startConfirmationService(componentName, userHandle, key, fingerprints)) { return; } Slog.e(TAG, "unable to start customAdbPublicKeyConfirmation[SecondaryUser]Component " + componentString + " as an Activity or a Service"); } /** * @returns true if the componentName led to an Activity that was started. */ private boolean startConfirmationActivity(ComponentName componentName, UserHandle userHandle, String key, String fingerprints) { PackageManager packageManager = mContext.getPackageManager(); Intent intent = createConfirmationIntent(componentName, key, fingerprints); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) { try { mContext.startActivityAsUser(intent, userHandle); return true; } catch (ActivityNotFoundException e) { Slog.e(TAG, "unable to start adb whitelist activity: " + componentName, e); } } return false; }

其中,com.android.internal.R.string.config_customAdbPublicKeyConfirmationComponent 在 文件 frameworks/base/core/res/res/values/config.xml 中,值为

com.android.systemui/com.android.systemui.usb.UsbDebuggingActivity com.android.systemui/com.android.systemui.usb.UsbDebuggingSecondaryUserActivity

这样就清楚了,最终根据包名信息 com.android.systemui/com.android.systemui.usb.UsbDebuggingActivity 打开了“允许USB调试吗” 页面。

总结如下:

1.开机后启动 UsbService ,UsbDebuggingThread 一直检测 adb 消息; 2.收到 adb connect 消息后,通过 UsbDebuggingHandler 调起 SystemUI 的 UsbDebuggingActivity 页面。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3