当我们调试安卓机器时,第一次插上usb线,会弹出一个授权的对话框,(前提是打开了usb调试功能)点击确认,才会允许调试.

如果我们想机器默认就可以调试该怎么做呢?

如果我们想动态拦截,需要用户输入帐号密码,才确认是否可以调试,该怎么做呢?或者只是单纯的想改变这个不好看的UI,又该怎么做呢?

分析的源码基于android 5.0.2_r1

前面所说的情况1,想在默认情况下就允许usb调试,需要修改源码下的/build/core/main.mk文件,然后重新编译,刷机,具体请看: 
http://blog.csdn.net/fanmengke_im/article/details/28389439?utm_source=tuicool&utm_medium=referral

至于后面的那一种,就是我要说的重点,需要去看一看android源码,然后做一些适当的修改.首先,我们要找到关于usb的源码,主要在/frameworks/base/services/java/目录下,也就是这几个文件: 
UsbDebuggingManager.java 
UsbDeviceManager.java 
UsbHostManager.java 
UsbService.java 
UsbSettingsManager.java

其中涉及到的一些资源文件在/frameworks/base/core/res/res/目录下

寻找入口点
源码与资源文件都在这了,从哪入手,我也是一头雾水,还好,只有5个java文件,去读一读,看看有什么收获. 
你会发现,在UsbDebuggingmanager类中,你会发现有这样的几个方法:

startConfirmation(String key, String fingerprints)

startConfirmationActivity(ComponentName componentName, String key,
            String fingerprints)

startConfirmationService(ComponentName componentName, String key,
            String fingerprints) 
1
2
3
4
5
6
7
会不会就是这些方法弹出了对话框呢?继续追踪,发现startConfirmationActivity()和startConfirmationService()都是在startConfirmation()方法中调用的,现在我们来看下startConfirmation()方法:

首先通过资源文件拿到一个String类型的nameString,然后通过unflattenFromString()方法,传入nameString得到一个ComponentName对象,那么nameString到底是什么呢?

在/frameworks/base/core/res/res/values/config.xml 文件中,我们看到:

原来ConponentName就是: 
包名为com.android.systemui 
组件为com.android.systemui.usb.UsbDebuggingActivity的类

弹窗UI在这修改

哦哦,原来我们弹出的授权对话框就是systemui app中的一个activity,如果你只是单纯的想改变这个UI,你现在只要到/frameworks/base/packages/SystemUI/usb/目录下,找到UsbDebuggingActivity这个类,修改它的布局文件即可.等会再来看下这个类,做了哪些事情.

继续回到上面的分析,你会发现startConfirmation()方法在一个Handler被调用,什么情况下会出发这个Handler呢?原来,UsbDebuggingManager实现了Runnable,在run()方法中开启了一个LocalSocket,去读取底层的usb信息,做出响应的操作.至于该线程的开启,也在Handler中,只要你调用了setAdbEnabled(),如果参数为true,就开启该线程.

现在我们只要看看在哪个地方实例化了UsbDebuggingManager类,调用了setAdbEnabled()方法.

追踪发现在UsbDeviceManager中,它的构造方法中初始化了UsbDebuggingManager类.

可以看到会通过SystemProperties读取ro.adb.secure 和 vold.decrypt的值,这两个值,我请教了做rom的同事,说这些值是在编译的时候修改的,主要来区分user,eng版本,这两个值主要就是来进行是否进行usb认证机制的.

然后就初始化了UsbDeviceManager类,在看看调用mDebuggingManager.setAdbEnabled(mAdbEnabled)的地方.

也是在UsbDeviceManager的Handler中调用的,它注册啦一个开机广播,每次开机就会触发它.代码只截取了一小部分…

当然,还有几个地方调用了setAdbEnabled()方法,比如在这个Handler初始化的时候,我就没有追踪了,如果你有兴趣,可以去调试下~

接下来,继续往上追踪,看看UsbDeviceManager在哪被实例化了.它是通过UsbService的构造方法来实例化的.

在UsbService这个类中,它是继承自IUsbManager.Stub类的,也就是IUsbManager.aidl这个文件,它在/frameworks/base/core/java/android/hardware/usb/文件夹下,这个接口是@hide的,因为外部不可以引用,文件内容如下:

// 只摘录了IUsbManager中的几个方法
/** @hide */
interface IUsbManager{

/* Allow USB debugging from the attached host. If alwaysAllow is true, add the
     * the public key to list of host keys that the user has approved.
     */
    void allowUsbDebugging(boolean alwaysAllow, String publicKey);

/* Deny USB debugging from the attached host */
    void denyUsbDebugging();

/* Clear public keys installed for secure USB debugging */
    void clearUsbDebuggingKeys();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
看方法名就大致能猜出来该方法的作用,允许授权,拒绝授权,清除授权.

在看看UsbService在哪被实例化?在UsbService中有一个Lifecycle静态内部类,继承自SystemService,在onStart()方法中,实例化了UsbService类.

那是在何处调用了Lifecycle类呢?通过查找发现,原来是在SystemService这个类调用的.

对于SystemService类,我也不是很了解,具体的相关信息可以去查询.SystemService是android系统一个很重要的服务,它是由zytote来初始化的,然后会启动android系统的一些必要服务和支持组件,地位相当重要.直接看看代码吧.

private void run() {
        // If a device's clock is before 1970 (before 0), a lot of
        // APIs crash dealing with negative numbers, notably
        // java.io.File#setLastModified, so instead we fake it and
        // hope that time from cell towers or NTP fixes it shortly.
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

// Here we go!
        Slog.i(TAG, "Entered the Android system server!");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());

// In case the runtime switched since last boot (such as when
        // the old runtime was removed in an OTA), set the system
        // property so that it is in sync. We can't do this in
        // libnativehelper's JniInvocation::Init code where we already
        // had to fallback to a different runtime because it is
        // running as root and we need to be the system user to set
        // the property. http://b/11463182
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

// Enable the sampling profiler.
        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            mProfilerSnapshotTimer = new Timer();
            mProfilerSnapshotTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    SamplingProfilerIntegration.writeSnapshot("system_server", null);
                }
            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }

// Mmmmmm... more memory!
        VMRuntime.getRuntime().clearGrowthLimit();

// The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

// Some devices rely on runtime fingerprint generation, so make sure
        // we've defined it before booting further.
        Build.ensureFingerprintProperty();

// Within the system server, it is an error to access Environment paths without
        // explicitly specifying a user.
        Environment.setUserRequired(true);

// Ensure binder calls into the system always run at foreground priority.
        BinderInternal.disableBackgroundScheduling(true);

// Prepare the main looper thread (this thread).
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();

// Initialize native services.
        System.loadLibrary("android_servers");
        nativeInit();

// Check whether we failed to shut down last time we tried.
        // This call may not return.
        performPendingShutdown();

// Initialize the system context.
        createSystemContext();

// Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

// Start services.
        try {
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        }

// For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

// Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
可以看到初始化很多东西,创建Context,加载android_servers,初始化主线程…最后调用了startBootstrapServices(),startCoreServices(),startOtherServices()方法,在这个方法中,启动了Lifecycle服务.

这样的话,整体流程就串起来了. 
1.首先android系统启动,初始化了SystemServer 
2.在由SystemServer去启动UsbService$Lifecycle服务,然后实例化UsbService 
3.在由UsbService初始化了UsbHostManager和UsbDeviceManager. 
4.然后UsbDeviceManager通过读取ro.adb.secure和vold.decrypt的值,来判定是否开启调试拦截流程(也就是初始化UsbDebuggingManager) 
5.如果初始化UsbDebuggingManager,它会一直监听LocalSocketAddress(“adbd”, LocalSocketAddress.Namespace.RESERVED)这个端口,判断是否弹出授权窗口

分析弹出授权的UI窗口

也就是UsbDebuggingActivity类,继承自AlertActivity,我们主要看一些确认和取消的事件.

通过ServiceManager得到一个IBinder对象,然后通过IBinder得到一个IUsbManager对象,这个就是前面所说的aidl接口,UsbService实现了IUsbManager接口,调用allowUsbDebugging()和denyUsbDebugging(),同意授权和不同意授权.

那我们在回过头来,看一看IUsbManager接口中的allowUsbDebugging()和denyUsbDebugging()的实现. 
在UsbService中:

其实调用的是UsbDeviceManager中的方法:

最终发现原来调用的是UsbDebuggingManager中的方法:

最终,找到了原来所有的操作还是在它的UsbDebuggingHandler中,如果授权成功了,会向文件中写入这个key和相关信息,然后通过上面所说的Socket写入一条”OK”这样的信息.如果取消授权,会通过Socket写入一条”NO”这样的信息.到此,整个流程就走完了.

至于Socket的另一端,暂时没有去寻找它,据个人估计,可能与驱动方面有关.(咱待研究)

定制调试拦截
1.如果你只是想改动弹出的UI,只需要修改UsbDebuggingActivity的布局文件就可以了.

2.如该想改动相关逻辑,就需要在UsbDebuggingManager类中改动,是否弹窗,或者根本不想用systemui里面的Activity,都可以在这里面进行改动. 
不过上层如果想要授权的话,需要调用IUsbManager的授权和取消授权方法. 
如果获取不到该类或者它的实现类UsbService(好像是因为IUsbManager是@hide,我没有试过),建议你仿照IUsbManager.adil文件,上下层都去实现其中的几个重要方法,就可以拿来用了.

3.如果你根本想不拦截调试授权的话,就需要在main.mk文件中做一些相应的修改了,具体的话,可以去网上搜一下.

4.当然,如果你修改UsbDeviceManager类的,在初始化的时候给它再加一个判断条件的话,也可以显示自由拦截功能.

暂时就研究到这了,因为公司需要定制这东西,等需求有变化了,可能需要在做研究,到时候在补充吧~

相关文章: 
android4.4 debug调试授权拦截(替换掉 允许USB调试吗? UI) 
Android 如何开启与关闭adb 的认证机制(google adb secure) (adb RSA 指纹认证) 
Android 下的usb框架及功能点 
Android设备adb授权的原理
--------------------- 
作者:zhou_lee 
来源:CSDN 
原文:https://blog.csdn.net/u012301841/article/details/53200172 
版权声明:本文为博主原创文章,转载请附上博文链接!

Android 5.0 Usb调试拦截分析及修改相关推荐

  1. Android 11.0 Settings源码分析 - 主界面加载

    Android 11.0 Settings源码分析 - 主界面加载 本篇主要记录AndroidR Settings源码主界面加载流程,方便后续工作调试其流程. Settings代码路径: packag ...

  2. Android 8.0系统源码分析--Camera processCaptureResult结果回传源码分析

    相机,从上到下概览一下,真是太大了,上面的APP->Framework->CameraServer->CameraHAL,HAL进程中Pipeline.接各种算法的Node.再往下的 ...

  3. android机上没有usb调试模式吗,如何在Android上启用USB调试

    Android系统的手机以及平板电脑占有巨大的市场份额,当使用USB数据线完成电脑端与安卓手机端数据传输时,需要将安卓手机开启USB调试模式. 什么是USB调试?USB调试是一种模式,允许Androi ...

  4. Android6.0 usb默认MTP模式的修改方法

    Android6.0 usb默认MTP模式的修改方法 在6.0以前的系统 只需要修改默认的 persist.sys.usb.config 的值就可以了, 但是6.0,无论你怎能修改persist.sy ...

  5. Android 7.0来电全屏显示 如何修改

    在Android 7.0来电全屏显示 如何修改呢? 1.alps/frameworks\base\packages\SystemUI\src\com\android\systemui\statusba ...

  6. android 2.2 usb调试,小米 2/2S 开启USB调试模式

    我们要将小米 2/2S与电脑进行连接,就必须要打开小米 2/2S系统的调试模式,不同的系统版本打开调试模式的方法有所不同,在这里我们就谈谈小米 2/2S各种系统版本打开USB调试模式的方法. 1.针对 ...

  7. android 代码打开usb调试,Android手机USB调试在哪?安卓手机如何打开USB调试模式?...

    Android手机USB调试在哪?安卓手机如何打开USB调试模式?如果我们要将安卓手机连接到电脑上,从而传输文件.下载应用或ROOT等,都需要打开手机的USB调试模式.安卓系统的版本有很多,它们的打开 ...

  8. Android 6.0.1 Location Service 分析

    定位服务是手机上最常用的功能之一,据说也是相对比较简单的服务,所以从这里入手.其他系统服务的架构都是类似的.明白其中一个之后,再去理解其他的会容易得多.下面以 Android 源码为基础,大致分析了 ...

  9. Android 8.0系统源码分析--开篇

    个人分类: Android框架总结Android源码解析android framework 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sinat ...

最新文章

  1. (2)hibernate HQL命名查询和Query接口的分页查询
  2. APP技巧:手机该不该每天关机一次?看完才恍然大悟!
  3. FR帧中继(点对点子接口)
  4. Android音频开发(六)音频编解码之初识MediaCodec上
  5. Map集合转换成实体类对象,实体类对象转换为map集合,互转工具类
  6. H.264中的指数哥伦布解码
  7. 多个Excel合并为一个Excel表
  8. Linux信号量以及互斥体
  9. Qt phonon 多媒体框架
  10. 计算机分析桁架受力,桁架的结构设计和受力分析
  11. android icloud照片恢复软件,iCloud照片怎么恢复到手机 iCloud照片恢复到手机方法【详细步骤】...
  12. java必会单词_java必会的英语单词
  13. 不能装载文档控件。请在检查浏览器的选项中检查浏览器的安全设置_Windows 7 怎么修复 Windows 中的 Wi-Fi 连接问题,我教你(六)...
  14. MOSFET管(MOS管)基础
  15. MathType的下载和安装以及添加到word中
  16. 88hash 饰品交易平台 立刻取回的csgo开箱网站
  17. PyQt5界面、美化(pyqt炫酷界面好看界面)
  18. [含论文+源码等]ssm实现的酒店管理系统[包运行成功]
  19. 利用python制作语音变声器,这么牛的技术还不来学?
  20. android自定义空的view,ListView android中的自定义空视图

热门文章

  1. 彩色图像分割MATLAB代码
  2. Python 3 os.walk使用详解
  3. 用GPUDirect RDMA技术做的代码测试
  4. 从其它地方复制的代码到VS 提示无法识别的标记的解决办法
  5. 科大星云诗社动态20210811
  6. 我用 PyTorch 复现了 LeNet-5 神经网络(CIFAR10 数据集篇)!
  7. java获取异常的数据_Java(8题):异常,通过try catch进行处理,登录,商品,使用jdbc进行读取,详细图析...
  8. Matlab神经网络十讲(7): Adaptive Filter and Adaptive Training
  9. 小波的秘密2_MATLAB图像多尺度分析
  10. [OS复习]操作系统综述1