原件: https://blog.csdn.net/KC 58236582/article/details/50351813
代码叠加机制
代码overlay的工作原理是将使用Android本机代码修改的文件单独放置在目录中。 编译代码时,它会检测到该目录中的文件。 如果该目录中的文件与原生文件相同,请将该文件放入编译的源文件中,然后从编译的源文件中删除与原生文件具有相同文件名的文件。
这样做有什么好处呢? 例如,我们与客户合作,添加了我们自己代码中的功能,并移动了本机代码,但我们的客户可能不需要此功能。 那么,我们必须在母语之上移除这个代码。 例如,使用git revert等。
但是,如果有这样的代码overlay机制,删除修改后的代码文件就可以了。 这样,系统就会将本机文件放入编译的源文件中并参与编译。
1 .创建1.overlay文件。 例如,必须对本机电源管理器服务进行更改。 首先,在服务器代码的根目录中创建一个类似于overlay的目录。 本机电源管理器服务目录为:框架/基本/服务
如果要修改此文件,请首先复制电源管理器服务代码并将其放置在目录中。 重叠/框架/基本/服务/核心/Java/com/Android/server/power
然后修改此目录下的电源管理器服务。
2 .修改Android.MK文件修改代码后,就是修改编译的Android.MK文件。 修改此文件分为两个阶段。 第一步是我们修改代码并将其添加到编译中,第二步是从编译中删除本机的同一文件。
2.1将修改后的代码添加到编译中。 此外,在上例的PowerManagerService中,相应的Android.mk位于目录中。
框架/基本/服务/核心
首先查看本机Android.mk文件:
LOCAL_PATH :=$(call my-dir )
include $(CLEAR_VARS )
local _ module :=services.core
LOCAL_SRC_FILES =
$ (呼叫Java-files-under,Java () ) )
Java/com/Android/server/event log tags.logtags
Java/com/Android/server/am/event log tags.logtags
local _ Java _ libraries 3360=telephony-common
local _ static _ Java _ libraries :=tz data _ update
include $ (build _ static _ Java _ library )
首先正在修改此文件:
第一步是将文件放入此变量中,因为名为LOCAL_SRC_FILES的变量代码参与了编译的文件。
services _ ext _ subdirs 3360=$ (add prefix ./././overlay /,$ ) _path )/)
services _ ext _ files 3360=$ (呼叫- Java-files-under,$(services_ext_subdirs ) )
local _ src _ files=$ (services _ ext _ files )
上面代码中的LOCAL_PATH表示当前目录。 是框架/基本/服务/核心
因此,要找到我们的overlay代码目录,必须首先退出框架。 因此,LOCAL_PATH的前缀为.//.//./Overlay/,后跟overlay/frameworks/base/services/cervices
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
{
.............
//set cpu boost
void boostForPerformance(int cpu_nr, int duration);
void printPower();//新增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))//base 编译java文件目录
#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))//overlay下java文件
$(warning $(base_file_overlay_subdir))
overlay_java_file = $(call find-other-java-files,$(base_file_overlay_subdir))
LOCAL_SRC_FILES += $(overlay_java_file)//把overlay下面base对应目录的java文件加入编译
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
LEADCORE_OVERLAY := true
最后就是PowerManagerService.java的编译,前面分析过了,这边再简单介绍下:
先在PowerManagerService.java中修改PowerManagerService里的BinderService增加一个接口如下:
private final class BinderService extends IPowerManager.Stub {
.........
@Override // Binder call
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就完成了。