假设项目名是:mt1234
1、
找到mt1234/ProjectConfig.mk文件,将下面两个宏置为no:
MTK_HDMI_HDCP_SUPPORT = noMTK_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: yProjectConfig Setting: no*** Boolean ERROR ***: CONFIG_MTK_HDMI_SUPPORT not sync with MTK_HDMI_SUPPORT in ProjectConfig.mkKconfig Setting: yProjectConfig 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/
接着根据搜索结果自行判定这个字符串的来历,比如这里是个字符串:
<string name="hdmi_settings">HDMI settings</string>
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:182packages/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_SERVICEmHdmiManager = 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);/// 设置 summarymHdmiSettings.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=1endif
到这里宏开关MTK_HDMI_SUPPORT就暴露出来了。接下来就可以按前面介绍的步骤去关闭相应的宏开关了。
实际在 device/mediatek/common/device.mk 可能找到多出 HDMI 相关的宏定义,如下:
ifeq ($(strip $(MTK_HDMI_SUPPORT)), yes)PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_support=1endififeq ($(strip $(MTK_MT8193_HDMI_SUPPORT)), yes)PRODUCT_PROPERTY_OVERRIDES += ro.mtk_mt8193_hdmi_support=1endififeq ($(strip $(MTK_HDMI_HDCP_SUPPORT)), yes)PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_hdcp_support=1endififeq ($(strip $(MTK_INTERNAL_HDMI_SUPPORT)), yes)PRODUCT_PROPERTY_OVERRIDES += ro.mtk_internal_hdmi_support=1endif
它们分别是做什么的,我们也不知道,但可以确定的是和 HDMI 相关,如果要彻底屏蔽 HDMI 功能,不妨将他们都关掉。
