点击打开链接

代码overlay机制意思是,将我们在Android原生代码上修改过的文件,单独放在一个目录下,而在编译代码的时候就会去检测这个目录下的文件,如果这个目录下的文件与原生有相同的文件,那么就将这个文件放入编译的源文件中,而将原生相同文件名的文件从编译的源文件中去除。

这样做有什么好处呢,比如我们和客户合作,在我们自己的代码上加了某一个功能,于是动了原生的代码,而我们的客户有时候不需要这个功能,那么我们必须在原生上面去除这个代码,比如用git revert等。

但是如果我们有这样一个代码overlay的机制,我们只要将我们修改的代码文件去除就可以,这样系统就会把原生的文件放入编译的源文件中加入编译。

1.建立overlay的文件

比如我们需要对原生的PowerManagerService进行修改,首先我们先在服务器代码根目录建立一个比如:overlay这样一个目录,原生PowerManagerService的目录: frameworks/base/services/core/java/com/android/server/power/PowerManagerService,

那么如果我们对这个文件修改,先拷贝一份PowerManagerService代码放在目录:overlay/frameworks/base/services/core/java/com/android/server/power/PowerManagerService,

然后再去对这个目录下的PowerManagerService进行修改。

2.修改Android.mk文件

修改好了代码之后,就是修改编译的Android.mk文件,修改这文件分为两步,第一步是将我们修改代码加入编译,第二步是将原生相同文件从编译中去除。

2.1将修改的代码加入编译

我们还是举例上面的PowerManagerService,其对应的Android.mk在目录:

frameworks/base/services/core

我们先来看下原生的Android.mk文件:

[html] view plain copy
  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_MODULE := services.core
  4. LOCAL_SRC_FILES += \
  5. $(call all-java-files-under,java) \
  6. java/com/android/server/EventLogTags.logtags \
  7. java/com/android/server/am/EventLogTags.logtags
  8. LOCAL_JAVA_LIBRARIES := telephony-common
  9. LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
  10. include $(BUILD_STATIC_JAVA_LIBRARY)

我们先在修改这个文件:

LOCAL_SRC_FILES这个变量代码参与编译的文件,因此我们第一步就是将我们的文件放入这个变量中:

[html] view plain copy
  1. services_ext_subdirs := $(addprefix ../../../../overlay/, $(LOCAL_PATH)/)
  2. services_ext_files := $(call all-java-files-under,$(services_ext_subdirs))
  3. LOCAL_SRC_FILES += $(services_ext_files)

上面代码中LOCAL_PATH代表当前目录:frameworks/base/services/core

因此要找到我们的overlay代码目录,先要跳出frameworks这层,因此在LOCAL_PATH前面加了../../../../overlay/这个前缀就到了overlay/frameworks/base/services/core目录了,我们再查找这个目录下的java文件,加入到LOCAL_SRC_FILES这个变量中就把我们修改的文件加入到编译中了。

2.2将原生相同文件从编译中去除

下面我们需要将原生相同文件从编译中去除,也就是把文件从LOCAL_SRC_FILES这个变量中移除。

我们来看下代码实现:

[html] view plain copy
  1. empty :=
  2. services_ext_overlay_files := $(subst $(services_ext_subdirs),$(empty),$(services_ext_files))
  3. LOCAL_SRC_FILES := $(filter-out $(services_ext_overlay_files), $(LOCAL_SRC_FILES))

先把前面上一节中找到的java文件中前缀overlay/frameworks/base/services/core的直接把这个前缀替换掉了,可以理解是直接删除了这个前缀。

比如PowerManagerService现在变成:

java/com/android/server/power/PowerManagerService

最后一行利用filter-out将上面这个文件从LOCAL_SRC_FILES中去除,也就是将原生的文件从编译中去除。

这样就达到了代码overlay的目的。

3.例子(修改PowerManager、IPowerManager.aidl、PowerManagerService)

当然这里只是修改了PowerManagerService,下面我们通过PowerManager、IPowerManager.aidl整个修改来说下这个代码overlay机制。

首先我们先修改IPowerManager.aidl:新增一个printPower接口

[java] view plain copy
  1. interface IPowerManager
  2. {
  3. .............
  4. //set cpu boost
  5. void boostForPerformance(int cpu_nr, int duration);
  6. void printPower();//新增printPower接口
  7. }

下面是PowerManager.java中的修改:

[java] view plain copy
  1. .......
  2. public void printPower() {
  3. try {
  4. mService.printPower();
  5. } catch (RemoteException e) {
  6. }
  7. }
  8. ......

当然这两个文件时overlay,我们需要重新放在overlay/frameworks/base/services/core/java/android/os/IPowerManager.aidl;

overlay/frameworks/base/services/core/java/android/os/PowerManager.java

3.1 修改frameworks/base/Android.mk

下一步我们就看frameworks/base/Android.mk里面的修改:

[java] view plain copy
  1. include $(CLEAR_VARS)
  2. # FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
  3. LOCAL_SRC_FILES := $(call find-other-java-files,$(FRAMEWORKS_BASE_SUBDIRS))//base 编译java文件目录
  4. #overlay
  5. ifeq ($(LEADCORE_OVERLAY),true)//自己定义一个宏开关
  6. base_file_overlay_prefix := $(addprefix ../../overlay/, $(LOCAL_PATH)/)
  7. base_file_overlay_subdir := $(addprefix $(base_file_overlay_prefix), $(FRAMEWORKS_BASE_SUBDIRS))//overlay下java文件
  8. $(warning $(base_file_overlay_subdir))
  9. overlay_java_file = $(call find-other-java-files,$(base_file_overlay_subdir))
  10. LOCAL_SRC_FILES += $(overlay_java_file)//把overlay下面base对应目录的java文件加入编译
  11. empty :=
  12. base_overlay_files := $(subst $(base_file_overlay_prefix),$(empty),$(overlay_java_file))
  13. $(warning $(base_overlay_files))
  14. LOCAL_SRC_FILES := $(filter-out $(base_overlay_files), $(LOCAL_SRC_FILES))
  15. endif

下面再来看看aidl文件的overlay:

[html] view plain copy
  1. LOCAL_SRC_FILES += \
  2. core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
  3. core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
  4. core/java/android/accounts/IAccountManager.aidl \
  5. core/java/android/accounts/IAccountManagerResponse.aidl \
  6. core/java/android/accounts/IAccountAuthenticator.aidl \
  7. core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
  8. core/java/android/app/IActivityContainer.aidl \
  9. core/java/android/app/IActivityContainerCallback.aidl \
  10. core/java/android/app/IActivityController.aidl \
  11. ..........
  12. #aidl files overlay
  13. ifeq ($(LEADCORE_OVERLAY),true) //宏开关
  14. //定义了一个变量用来去除原生的aidl文件的
  15. LOCAL_SRC_FILES := $(filter-out $(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES), $(LOCAL_SRC_FILES))
  16. //加入overlay下对应原生去除的aidl文件
  17. LOCAL_SRC_FILES += $(base_file_overlay_prefix)$(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES)
  18. //打印调试
  19. $(warning $(base_file_overlay_prefix)$(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES))
  20. endif

前PowerManager.java可以做到自动化,为什么aidl做不到呢?因为在base的Android.mk中aidl都是一个一个选出来的,就连同一目录有的参与编译,有的不参与编译,为了简单起见做了一个变量FRAMEWORKS_BASE_OVERLAY_AIDL_FILES来保存去除原生aidl文件。

3.2 系统变量定义

下面我们看下这个变量的定义:其实在build/core/pathmap.mk

[html] view plain copy
  1. FRAMEWORKS_BASE_OVERLAY_AIDL_FILES := \
  2. core/java/android/os/IPowerManager.aidl

顺便看下宏开关的定义在build/core/envsetup.mk

[html] view plain copy
  1. LEADCORE_OVERLAY := true

最后就是PowerManagerService.java的编译,前面分析过了,这边再简单介绍下:

先在PowerManagerService.java中修改PowerManagerService里的BinderService增加一个接口如下:

[java] view plain copy
  1. private final class BinderService extends IPowerManager.Stub {
  2. .........
  3. @Override // Binder call
  4. public void printPower() {
  5. Slog.e(TAG, "printPower");
  6. }
  7. ........

3.3修改frameworks/base/services/core/Android.mk

下面就是修改frameworks/base/services/core/Android.mk文件

[html] view plain copy
  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_MODULE := services.core
  4. LOCAL_SRC_FILES += \
  5. $(call all-java-files-under,java) \
  6. java/com/android/server/EventLogTags.logtags \
  7. java/com/android/server/am/EventLogTags.logtags
  8. $(warning $(LOCAL_PATH))
  9. #overlay
  10. ifeq ($(LEADCORE_OVERLAY),true)
  11. services_ext_subdirs := $(addprefix ../../../../overlay/, $(LOCAL_PATH)/)
  12. $(warning $(services_ext_subdirs))
  13. services_ext_files := $(call all-java-files-under,$(services_ext_subdirs))
  14. LOCAL_SRC_FILES += $(services_ext_files)
  15. $(warning $(services_ext_files))
  16. empty :=
  17. services_ext_overlay_files := $(subst $(services_ext_subdirs),$(empty),$(services_ext_files))
  18. $(warning $(services_ext_overlay_files))
  19. LOCAL_SRC_FILES := $(filter-out $(services_ext_overlay_files), $(LOCAL_SRC_FILES))
  20. endif
  21. LOCAL_JAVA_LIBRARIES := telephony-common
  22. LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
  23. include $(BUILD_STATIC_JAVA_LIBRARY)

这样整个修改power就完成了。

代码Overlay机制相关推荐

  1. Linux下一种 ELF 文件的代码签名验证机制

    1 引言 随着 Linux 的不断发展,已有越来越多的人开始推广和使用 Linux,其安全性也受到越来越多的挑战.ELF(Executable and Linkable Format)[1]作为 Li ...

  2. android 混淆后的机制,Android 代码混淆机制

    Android 代码混淆机制 由于Android项目是基于java语言的,而java属于高层抽象语言,易于反编译,其编译后的程序包包含了大量的源代码变量.函数名.数据结构等信息,根据其编译打包后的AP ...

  3. 金山卫士开源代码----消息机制浅析 (上

    博客已迁移至:http://kulv.sinaapp.com/,这里不再使用 金山卫士开源代码----消息机制浅析 (上) 代码地址:http://download.csdn.net/source/3 ...

  4. 中学再不学编程就晚了?MIT、JHU研究:程序员大脑思考代码的机制不对劲

    视学算法报道 转载自:机器之心 编辑:泽南.小舟 MIT.约翰霍普金斯大学的研究人员发现,思考编程并不像组织语言,但也不靠纯粹的逻辑.这是因为我们通常是在成年之后才开始学代码? 很多时候,我们认为优秀 ...

  5. 【Android安全】Android app开发者证书和代码签名机制

    参考链接: 安卓证书相关验证机制: https://duanqz.github.io/2017-09-01-Android-Digital-Signature (部分内容不准确) 关于META-INF ...

  6. 深入理解JVM之代码执行机制与线程资源同步及交互机制

    Java规范定义标准结构如图3.1 Java代码的执行机制 Java源码编译机制 javac将Java源码编译为class文件的步骤如图3.2 1.分析和输入到符号表(Parse and Enter) ...

  7. Git 的代码管控机制

    Git 由于他自身的优势和灵活性,已经渐渐取代了SVN,作为代码管控的首选工具. 先聊聊用git 来管控代码,我们到底需要多少分支才算是一个比较OK的选择呢: 答案是: Master 分支 + Dev ...

  8. java垃圾收集的目的_()、()和()使Java的设计目的得以实现?A、Java虚拟机B、垃圾收集机制C、三级代码安全检查机制D、Serv...

    提出德育的认知模式的学者是____. 与引起心肌收缩性减弱的基本机制无关的是()A.心肌收缩的蛋白(收缩蛋白.调节蛋白)被破坏B.心肌 企业应当在利润表中分别列示()和终止经营损益.A.持续经营收入B ...

  9. java代码的执行机制_关于java代码的执行机制

    转载于:https://blog.csdn.net/houfeng777123/article/details/74316748 1.Java代码执行流程 ·第一步:*.java-->*.cla ...

最新文章

  1. linux服务器读写硬盘io,查看linux服务器硬盘IO读写负载
  2. Cloudify — Plugins
  3. 接口 500_python接口的自我修炼之路
  4. MySQL作为Kubernetes服务,可从WildFly Pod访问
  5. POJ 计算几何(3)
  6. django 的请求处理部分----WSGIHandler 源码分析 django1.5.5
  7. 这类程序员,钱包要鼓了!
  8. lua 去除小数点有效数字后面的0_【物联网学习番外篇】Lua脚本编程扫盲
  9. 【CCCC】L2-005 集合相似度 (25分),维护set数组去重,比较统计
  10. pytorch test单张图片_PyTorch的元学习库:Torchmeta
  11. 【牛客练习赛58-C】矩阵消除游戏(dfs+状态标记)
  12. Android 中多点触摸协议
  13. 富士通MB95F636H输出PWM
  14. 计算机图形学——Liang-Barsky算法
  15. Win10+1050Ti配置Tensorflow教程
  16. 【水滴石穿】ES must与should组合使用的正确方式
  17. winform 分页打印实例
  18. 机器学习:simple linear iterative clustering (SLIC) 算法
  19. matlab求解微分方程解析解
  20. Hello C(八)——内存字节对齐

热门文章

  1. exe打包工具_pyqt5快速上手基础篇12-使用Pyinstaller打包应用程序
  2. Windoes上安装(升级)虚拟化VMware Workstattion Pro软件、序列码激活软件
  3. 切割机插件_这些激光切割机的故障,看看你都遇到过吗?
  4. Day1-java基本类型
  5. SpringBoot--HelloWord
  6. xml显示浏览器标签_浅析浏览器书签的导入和导出
  7. python怎么返回最初_Python 函数为什么会默认返回 None?
  8. Linux 解压缩tar经历,Linux命令 -- tar解压缩命令
  9. linux系统中定时器使用方法,Linux下实现定时器Timer的几种方法
  10. android8 静音震动,iPhone8开启静音后手机振动怎么办?苹果8关闭静音模式震动的两种方法...