转自:http://blog.csdn.net/kc58236582/article/details/50351813
感谢原作者分享,转载仅供收藏用,如有冒犯请告知。
代码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文件:
- LOCAL_PATH := $(call my-dir)
-
- include $(CLEAR_VARS)
-
- LOCAL_MODULE := services.core
-
- LOCAL_SRC_FILES += \
- $(call all-java-files-under,java) \
- java/com/android/server/EventLogTags.logtags \
- java/com/android/server/am/EventLogTags.logtags
-
- LOCAL_JAVA_LIBRARIES := telephony-common
- LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
-
- include $(BUILD_STATIC_JAVA_LIBRARY)
我们先在修改这个文件:
LOCAL_SRC_FILES这个变量代码参与编译的文件,因此我们第一步就是将我们的文件放入这个变量中:
- services_ext_subdirs := $(addprefix ../../../../overlay/, $(LOCAL_PATH)/)
-
- services_ext_files := $(call all-java-files-under,$(services_ext_subdirs))
-
- 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这个变量中移除。
我们来看下代码实现:
- empty :=
-
- services_ext_overlay_files := $(subst $(services_ext_subdirs),$(empty),$(services_ext_files))
-
- 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接口
- interface IPowerManager
- {
- .............
-
-
- void boostForPerformance(int cpu_nr, int duration);
- void printPower();
- }
下面是PowerManager.java中的修改:
- .......
- public void printPower() {
- try {
- mService.printPower();
- } catch (RemoteException e) {
- }
- }
- ......
当然这两个文件时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里面的修改:
- include $(CLEAR_VARS)
-
- # FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
- LOCAL_SRC_FILES := $(call find-other-java-files,$(FRAMEWORKS_BASE_SUBDIRS))
-
- #overlay
- ifeq ($(LEADCORE_OVERLAY),true)
- base_file_overlay_prefix := $(addprefix ../../overlay/, $(LOCAL_PATH)/)
- base_file_overlay_subdir := $(addprefix $(base_file_overlay_prefix), $(FRAMEWORKS_BASE_SUBDIRS))
- $(warning $(base_file_overlay_subdir))
- overlay_java_file = $(call find-other-java-files,$(base_file_overlay_subdir))
- LOCAL_SRC_FILES += $(overlay_java_file)
-
- empty :=
- base_overlay_files := $(subst $(base_file_overlay_prefix),$(empty),$(overlay_java_file))
- $(warning $(base_overlay_files))
-
- LOCAL_SRC_FILES := $(filter-out $(base_overlay_files), $(LOCAL_SRC_FILES))
- endif
下面再来看看aidl文件的overlay:
- LOCAL_SRC_FILES += \
- core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
- core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
- core/java/android/accounts/IAccountManager.aidl \
- core/java/android/accounts/IAccountManagerResponse.aidl \
- core/java/android/accounts/IAccountAuthenticator.aidl \
- core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
- core/java/android/app/IActivityContainer.aidl \
- core/java/android/app/IActivityContainerCallback.aidl \
- core/java/android/app/IActivityController.aidl \
- ..........
-
- #aidl files overlay
- ifeq ($(LEADCORE_OVERLAY),true) //宏开关
- //定义了一个变量用来去除原生的aidl文件的
- LOCAL_SRC_FILES := $(filter-out $(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES), $(LOCAL_SRC_FILES))
- //加入overlay下对应原生去除的aidl文件
- LOCAL_SRC_FILES += $(base_file_overlay_prefix)$(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES)
- //打印调试
- $(warning $(base_file_overlay_prefix)$(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES))
- endif
前PowerManager.java可以做到自动化,为什么aidl做不到呢?因为在base的Android.mk中aidl都是一个一个选出来的,就连同一目录有的参与编译,有的不参与编译,为了简单起见做了一个变量FRAMEWORKS_BASE_OVERLAY_AIDL_FILES来保存去除原生aidl文件。
3.2 系统变量定义
下面我们看下这个变量的定义:其实在build/core/pathmap.mk
- FRAMEWORKS_BASE_OVERLAY_AIDL_FILES := \
- core/java/android/os/IPowerManager.aidl
顺便看下宏开关的定义在build/core/envsetup.mk
最后就是PowerManagerService.java的编译,前面分析过了,这边再简单介绍下:
先在PowerManagerService.java中修改PowerManagerService里的BinderService增加一个接口如下:
- private final class BinderService extends IPowerManager.Stub {
- .........
- @Override
- public void printPower() {
- Slog.e(TAG, "printPower");
- }
- ........
3.3修改frameworks/base/services/core/Android.mk
下面就是修改frameworks/base/services/core/Android.mk文件
- LOCAL_PATH := $(call my-dir)
-
- include $(CLEAR_VARS)
-
- LOCAL_MODULE := services.core
-
- LOCAL_SRC_FILES += \
- $(call all-java-files-under,java) \
- java/com/android/server/EventLogTags.logtags \
- java/com/android/server/am/EventLogTags.logtags
-
- $(warning $(LOCAL_PATH))
-
- #overlay
- ifeq ($(LEADCORE_OVERLAY),true)
- services_ext_subdirs := $(addprefix ../../../../overlay/, $(LOCAL_PATH)/)
- $(warning $(services_ext_subdirs))
-
- services_ext_files := $(call all-java-files-under,$(services_ext_subdirs))
- LOCAL_SRC_FILES += $(services_ext_files)
- $(warning $(services_ext_files))
-
- empty :=
- services_ext_overlay_files := $(subst $(services_ext_subdirs),$(empty),$(services_ext_files))
- $(warning $(services_ext_overlay_files))
-
- LOCAL_SRC_FILES := $(filter-out $(services_ext_overlay_files), $(LOCAL_SRC_FILES))
- endif
-
- LOCAL_JAVA_LIBRARIES := telephony-common
- LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
-
- include $(BUILD_STATIC_JAVA_LIBRARY)
这样整个修改power就完成了。