假设项目名是:mt1234
1、
找到mt1234/ProjectConfig.mk
文件,将下面两个宏置为no
:
MTK_HDMI_HDCP_SUPPORT = no
MTK_HDMI_SUPPORT = no
清掉build.prop
及其中间文件后 remake,报错如下:
vendor/mediatek/proprietary/scripts/check_dep/android_dep_rule.mak:453:
*** PLEASE turn on MTK_HDMI_SUPPORT or turn off MTK_INTERNAL_HDMI_SUPPORT
./vendor/mediatek/proprietary/scripts/check_dep/Android.mk:58:
*** Dependency Check FAILED!!.
根据提示信息,我们知道这是个 Dependency Check,说明 MTK_HDMI_SUPPORT
和 MTK_INTERNAL_HDMI_SUPPORT
存在依赖关系,因此我们也同步置为 no
:
MTK_INTERNAL_HDMI_SUPPORT = no
再次 remake,这个时候往往还编译不过,会有下面的报错:
FAILED: /bin/bash -c "python device/mediatek/build/build/tools/check_kernel_config.py -c device/mediatek/em_ts701_p4rde/ProjectConfig.mk -k corebase_mt8167/kernel-4.4/drivers/misc/mediatek/.vendor/em_ts701_p4rde/kernel/configs/em_ts701_p4rde_defconfig -p em_ts701_p4rde"
Kconfig Setting: y
ProjectConfig Setting: no
*** Boolean ERROR ***: CONFIG_MTK_HDMI_SUPPORT not sync with MTK_HDMI_SUPPORT in ProjectConfig.mk
Kconfig Setting: y
ProjectConfig Setting: no
*** Boolean ERROR ***: CONFIG_MTK_INTERNAL_HDMI_SUPPORT not sync with MTK_INTERNAL_HDMI_SUPPORT in ProjectConfig.mk
还好明确说明了是宏开关状态不同步......
2、
找到mt1234_defconfig
文件,注释掉下面这两个宏:
# CONFIG_MTK_INTERNAL_HDMI_SUPPORT=y
# CONFIG_MTK_HDMI_SUPPORT=y
注意这里不能简单的置为
n
,否则也会导致编译不过。
修改完这个文件之后,编译user
版本就不会报错了,但是要想编译eng
版本也不会报错,还要做进一步修改。
3、
找到mt1234_debug_defconfig
文件,同样注释掉下面这两个宏:
# CONFIG_MTK_INTERNAL_HDMI_SUPPORT=y
# CONFIG_MTK_HDMI_SUPPORT=y
到这里编译eng
版本也就没问题了,全部修改完了。
4、
clean 了重新编译,不然很可能会出现卡在打包 systemimage 这里。
俗话说:授之以鱼不如授之以渔。
当我们碰到一个不知道宏开关名字的Feature
时,怎么去确定它的宏开关?
要想知道是怎么确定这些修改步骤的请往下看。
1、
在 Settings 源码里面搜索机器运行显示的信息,如搜索显示的HDMI settings
字符串:
$ grep "HDMI settings" -nrw packages/apps/Settings/
接着根据搜索结果自行判定这个字符串的来历,比如这里是个字符串:
HDMI settings
2、
接着搜索hdmi_settings
在什么地方被引用,为了提高搜索精度,我们可以这么写:
$ grep "string.hdmi_settings" -nrw packages/apps/Settings/
这样既能搜索到 @string/hdmi_settings
也能搜到 R.string.hdmi_settings
,结果如下:
packages/apps/Settings/src/com/mediatek/hdmi/HdmiSettings.java:182
packages/apps/Settings/src/com/mediatek/settings/DisplaySettingsExt.java:202
我们根据经验大致可以判断 /hdmi/HdmiSettings.java
应该是 HDMI 功能模块内部了,我们要屏蔽这个功能,应该从屏蔽入口做起,所以应该不是 /hdmi/HdmiSettings.java
。
3、
打开DisplaySettingsExt.java
查看202行
附近代码:
······
// add for HDMI Settings @ {
/// 获取 IMtkHdmiManager 对象,这里是个 AIDL 调用,我们关注下 Context.HDMI_SERVICE
mHdmiManager = IMtkHdmiManager.Stub.asInterface(ServiceManager
.getService(Context.HDMI_SERVICE));
/// 如果 mHdmiManager 不为 null,就进行下面的操作
if (mHdmiManager != null) {
/// 202 行在这里
/// 创建 HDMI 入口对应的 Preference 对象
mHdmiSettings = createPreference(TYPE_PREFERENCE, R.string.hdmi_settings,
KEY_HDMI_SETTINGS);
/// 设置 summary
mHdmiSettings.setSummary(R.string.hdmi_settings_summary);
/// 设置点击后要跳转的 Fragment,正好是我们前面推测的 HdmiSettings,
/// 至此,逻辑已经非常清晰了,下面的代码不解释了。
mHdmiSettings.setFragment("com.mediatek.hdmi.HdmiSettings");
try {
String hdmi = mContext.getString(R.string.hdmi_replace_hdmi);
if (mHdmiManager.getDisplayType() == HdmiDef.DISPLAY_TYPE_MHL) {
String mhl = mContext.getString(R.string.hdmi_replace_mhl);
mHdmiSettings.setTitle(mHdmiSettings.getTitle().toString()
.replaceAll(hdmi, mhl));
mHdmiSettings.setSummary(mHdmiSettings.getSummary().toString().replaceAll(hdmi,
mhl));
} else if (mHdmiManager.getDisplayType() == HdmiDef.DISPLAY_TYPE_SLIMPORT) {
String slimport = mContext.getString(R.string.slimport_replace_hdmi);
mHdmiSettings.setTitle(mHdmiSettings.getTitle().toString()
.replaceAll(hdmi, slimport));
mHdmiSettings.setSummary(mHdmiSettings.getSummary().toString().replaceAll(hdmi,
slimport));
}
} catch (RemoteException e) {
Log.d(TAG, "getDisplayType RemoteException");
}
mHdmiSettings.setOrder(PREFERENCE_ORDER_FIRST + 2);
screen.addPreference(mHdmiSettings);
······
这段代码逻辑很清晰,就是动态判断是否支持 HDMI 功能,若支持,则将 HDMI 相关入口显示出来,反之不显示。
4、
搜索Context.HDMI_SERVICE
看它是在什么地方被放入ServiceManager
的,显然这个操作应该是framework
级别的,所以为了提高搜索精度我们可以这么写:
$ grep "Context.HDMI_SERVICE" -nrw frameworks/
搜索结果如下:
frameworks/base/services/java/com/android/server/SystemServer.java:1357: ServiceManager.addService(Context.HDMI_SERVICE,
frameworks/base/services/core/java/com/android/server/display/WifiDisplayController.java:447: .getService(Context.HDMI_SERVICE));
5、
打开SystemServer.java
查看 1357行
附近的代码:
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
private void startOtherServices() {
/// 此处省略大量代码
/// M: add for HDMI feature @{
/// 满足这个 if 条件就执行下面的 add 操作
if (!disableNonCoreServices
&& SystemProperties.get("ro.mtk_hdmi_support").equals("1")) {
try {
Slog.i(TAG, "HDMI Manager Service");
/// 实例化 MtkHdmiManagerService 对象
hdmiManager = new MtkHdmiManagerService(context);
/// 对象绑定
ServiceManager.addService(Context.HDMI_SERVICE,
hdmiManager.asBinder());
} catch (Throwable e) {
Slog.e(TAG, "Failure starting MtkHdmiManager", e);
}
}
/// @}
/// 此处又省略大量代码
}
到这里 if 条件里面的ro.mtk_hdmi_support
就是关键了,它一般就直接和宏开关有联系了。
6、
搜索ro.mtk_hdmi_support
,因宏开关一般都在device目录
下,同样为了提高搜索精度,我们这么写:
$ grep "ro.mtk_hdmi_support" -nrw device/
搜索结果如下:
device/mediatek/common/device.mk:944: PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_support=1
就这一个结果,就是在这里将ro.mtk_hdmi_support
赋值为 1 了。
7、
打开device/mediatek/common/device.mk
,查看 944行
左右的代码:
ifeq ($(strip $(MTK_HDMI_SUPPORT)), yes)
PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_support=1
endif
到这里宏开关MTK_HDMI_SUPPORT
就暴露出来了。接下来就可以按前面介绍的步骤去关闭相应的宏开关了。
实际在 device/mediatek/common/device.mk
可能找到多出 HDMI 相关的宏定义,如下:
ifeq ($(strip $(MTK_HDMI_SUPPORT)), yes)
PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_support=1
endif
ifeq ($(strip $(MTK_MT8193_HDMI_SUPPORT)), yes)
PRODUCT_PROPERTY_OVERRIDES += ro.mtk_mt8193_hdmi_support=1
endif
ifeq ($(strip $(MTK_HDMI_HDCP_SUPPORT)), yes)
PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_hdcp_support=1
endif
ifeq ($(strip $(MTK_INTERNAL_HDMI_SUPPORT)), yes)
PRODUCT_PROPERTY_OVERRIDES += ro.mtk_internal_hdmi_support=1
endif
它们分别是做什么的,我们也不知道,但可以确定的是和 HDMI 相关,如果要彻底屏蔽 HDMI 功能,不妨将他们都关掉。