android4.4 debug调试授权拦截(替换掉 允许USB调试吗? UI)

做了4年的android 开发但都是在App应用层上的,最近公司转型做android智能硬件,碰到一些需求需要修改android源代码在这里做一下记录免得做完就忘了,属于rom开发的新手写的不对还望各位提点。
需求:当开发人员用usb调试线连接PC与android设备时弹出一个自定义UI界面,有两个按钮和一个输入框
- 手机号码输入框:输入手机号
- 获取验证码:点击向服务器请求一个手机号对应的验证码
- 确定:手机号与验证码如果与服务器一致则允许进入调试

了解相关原理和框架代码

android的adb debug调试是通过usb来完成的,首先要了解android设备是如何授权adb调试的还有android的usb相关架构及其代码。
这方面网上文章很多:
http://blog.csdn.net/sowhat_ah/article/details/43307907 (adb授权原理)
http://blog.csdn.net/tianruxishui/article/details/37902959 (usb框架)

android frameworks层的usb框架在 frameworks/base/services/java下的com.android.server.usb包中,我的源码在这个包下有这么几个文件:
- UsbDebuggingManager.java
- UsbDeviceManager.java
- UsbHostManager.java
- UsbService.java
- UsbSettingsManager.java

其中以UsbService.java(IUsbManager aidl接口实现)为基础来驱动框架的其他类文件,而UsbService.java是在com.android.server包下的ServerThread.java的initAndLoop()函数中被实例化的,以此为入口来了解usb框架的运行机制。(这部分后面再补上)

实现原理

修改ro.adb.secure默认值

android4.4通过一个名为 ro.adb.secure 的常量来控制是否弹出adb debug调试授权的窗口
在UsbDeviceManager.java构造函数中有这样一段代码:

        boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
        boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));

        if (secureAdbEnabled && !dataEncrypted) {
            mDebuggingManager = new UsbDebuggingManager(context);
        }

可以看到通过ro.adb.secure这个key拿到的boolean值secureAdbEnabled如果是true并且通过vold.decrypt这个key拿到的值不是”1”, 那么dataEncrypted是false,那么就会实例化一个UsbDebuggingManager对象,而UsbDebuggingManager对象就是弹出adb debug授权窗口的一整套流程的入口,至于vold.decrypt常量暂时还没去研究。
要注意的是通过ro.adb.secure这个key拿到的boolean值如果是false(有些源码平台默认是false的)那么就不会进入授权认证流程也就是不会弹出 允许USB调试吗? 的窗口直接就可以进行调试了而我这边的需求是要改变这个窗口的样式和按钮逻辑所以必须让它弹出来,如何改变ro.adb.secure的默认值网上也有很多文章:
http://www.tuicool.com/articles/UBF7ji (开启与关闭adb 的认证机制),解决这个之后或者你开发的源码平台默认就是开启的那么当你插入usb调试线连接PC与android设备的时候就会弹出一个窗口,这个窗口的弹出逻辑就是在UsbDebuggingManager.java中。

修改UsbDebuggingManager.java

在UsbDebuggingManager.java的showConfirmationDialog函数中:

    private void showConfirmationDialog(String key, String fingerprints) {
        Intent dialogIntent = new Intent();

        dialogIntent.setClassName("com.android.systemui",
                "com.android.systemui.usb.UsbDebuggingActivity");
        dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        dialogIntent.putExtra("key", key);
        dialogIntent.putExtra("fingerprints", fingerprints);
        try {
            mContext.startActivity(dialogIntent);
        } catch (ActivityNotFoundException e) {
            Slog.e(TAG, "unable to start UsbDebuggingActivity");
        }
    }

代码中的UsbDebuggingActivity就是授权弹出窗口的Activity在framewieks/base/packages/SystemUI/src下的com.android.systemui.usb包下。
实现我的需求有两种方法:
1.读懂并理解UsbDebuggingActivity的代码复制一个修改下文件名放在同一包下,根据需求修改下UI和逻辑然后在上面说道的showConfirmationDialog函数中启动我们自己的Activity窗口。
2.在showConfirmationDialog函数中使用AIDL接口与上层App通信通知上层弹出窗口,验证成功或者失败通过aidl回调控制是否允许adb调试,在源码中使用aidl文件需要在Android.mk文件中配置一下这个网上也可以查得到。

我使用的是第二种方法,这其中有许多细节我这次只是做一下记录,这里就不多写了反正大概思路就是这样,以后有机会再补充吧。

你可能感兴趣的:(android)