假设项目名是:mt1234
1、
找到mt1234/ProjectConfig.mk文件,将下面两个宏置为no

  1. MTK_HDMI_HDCP_SUPPORT = no
  2. MTK_HDMI_SUPPORT = no

清掉build.prop及其中间文件后 remake,报错如下:

  1. vendor/mediatek/proprietary/scripts/check_dep/android_dep_rule.mak:453:
  2. *** PLEASE turn on MTK_HDMI_SUPPORT or turn off MTK_INTERNAL_HDMI_SUPPORT
  3. ./vendor/mediatek/proprietary/scripts/check_dep/Android.mk:58:
  4. *** Dependency Check FAILED!!.

根据提示信息,我们知道这是个 Dependency Check,说明 MTK_HDMI_SUPPORTMTK_INTERNAL_HDMI_SUPPORT 存在依赖关系,因此我们也同步置为 no

  1. MTK_INTERNAL_HDMI_SUPPORT = no

再次 remake,这个时候往往还编译不过,会有下面的报错:

  1. 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"
  2. Kconfig Setting: y
  3. ProjectConfig Setting: no
  4. *** Boolean ERROR ***: CONFIG_MTK_HDMI_SUPPORT not sync with MTK_HDMI_SUPPORT in ProjectConfig.mk
  5. Kconfig Setting: y
  6. ProjectConfig Setting: no
  7. *** Boolean ERROR ***: CONFIG_MTK_INTERNAL_HDMI_SUPPORT not sync with MTK_INTERNAL_HDMI_SUPPORT in ProjectConfig.mk

还好明确说明了是宏开关状态不同步……

2、
找到mt1234_defconfig文件,注释掉下面这两个宏:

  1. # CONFIG_MTK_INTERNAL_HDMI_SUPPORT=y
  2. # CONFIG_MTK_HDMI_SUPPORT=y

注意这里不能简单的置为n,否则也会导致编译不过。

修改完这个文件之后,编译user版本就不会报错了,但是要想编译eng版本也不会报错,还要做进一步修改。

3、
找到mt1234_debug_defconfig文件,同样注释掉下面这两个宏:

  1. # CONFIG_MTK_INTERNAL_HDMI_SUPPORT=y
  2. # CONFIG_MTK_HDMI_SUPPORT=y

到这里编译eng版本也就没问题了,全部修改完了。

4、
clean 了重新编译,不然很可能会出现卡在打包 systemimage 这里。


俗话说:授之以鱼不如授之以渔。

当我们碰到一个不知道宏开关名字的Feature时,怎么去确定它的宏开关?
要想知道是怎么确定这些修改步骤的请往下看。

1、
Settings 源码里面搜索机器运行显示的信息,如搜索显示的HDMI settings字符串:

  1. $ grep "HDMI settings" -nrw packages/apps/Settings/

接着根据搜索结果自行判定这个字符串的来历,比如这里是个字符串:

  1. <string name="hdmi_settings">HDMI settings</string>

2、
接着搜索hdmi_settings在什么地方被引用,为了提高搜索精度,我们可以这么写:

  1. $ grep "string.hdmi_settings" -nrw packages/apps/Settings/

这样既能搜索到 @string/hdmi_settings 也能搜到 R.string.hdmi_settings,结果如下:

  1. packages/apps/Settings/src/com/mediatek/hdmi/HdmiSettings.java:182
  2. packages/apps/Settings/src/com/mediatek/settings/DisplaySettingsExt.java:202

我们根据经验大致可以判断 /hdmi/HdmiSettings.java 应该是 HDMI 功能模块内部了,我们要屏蔽这个功能,应该从屏蔽入口做起,所以应该不是 /hdmi/HdmiSettings.java

3、
打开DisplaySettingsExt.java查看202行附近代码:

  1. ······
  2. // add for HDMI Settings @ {
  3. /// 获取 IMtkHdmiManager 对象,这里是个 AIDL 调用,我们关注下 Context.HDMI_SERVICE
  4. mHdmiManager = IMtkHdmiManager.Stub.asInterface(ServiceManager
  5. .getService(Context.HDMI_SERVICE));
  6. /// 如果 mHdmiManager 不为 null,就进行下面的操作
  7. if (mHdmiManager != null) {
  8. /// 202 行在这里
  9. /// 创建 HDMI 入口对应的 Preference 对象
  10. mHdmiSettings = createPreference(TYPE_PREFERENCE, R.string.hdmi_settings,
  11. KEY_HDMI_SETTINGS);
  12. /// 设置 summary
  13. mHdmiSettings.setSummary(R.string.hdmi_settings_summary);
  14. /// 设置点击后要跳转的 Fragment,正好是我们前面推测的 HdmiSettings,
  15. /// 至此,逻辑已经非常清晰了,下面的代码不解释了。
  16. mHdmiSettings.setFragment("com.mediatek.hdmi.HdmiSettings");
  17. try {
  18. String hdmi = mContext.getString(R.string.hdmi_replace_hdmi);
  19. if (mHdmiManager.getDisplayType() == HdmiDef.DISPLAY_TYPE_MHL) {
  20. String mhl = mContext.getString(R.string.hdmi_replace_mhl);
  21. mHdmiSettings.setTitle(mHdmiSettings.getTitle().toString()
  22. .replaceAll(hdmi, mhl));
  23. mHdmiSettings.setSummary(mHdmiSettings.getSummary().toString().replaceAll(hdmi,
  24. mhl));
  25. } else if (mHdmiManager.getDisplayType() == HdmiDef.DISPLAY_TYPE_SLIMPORT) {
  26. String slimport = mContext.getString(R.string.slimport_replace_hdmi);
  27. mHdmiSettings.setTitle(mHdmiSettings.getTitle().toString()
  28. .replaceAll(hdmi, slimport));
  29. mHdmiSettings.setSummary(mHdmiSettings.getSummary().toString().replaceAll(hdmi,
  30. slimport));
  31. }
  32. } catch (RemoteException e) {
  33. Log.d(TAG, "getDisplayType RemoteException");
  34. }
  35. mHdmiSettings.setOrder(PREFERENCE_ORDER_FIRST + 2);
  36. screen.addPreference(mHdmiSettings);
  37. ······

这段代码逻辑很清晰,就是动态判断是否支持 HDMI 功能,若支持,则将 HDMI 相关入口显示出来,反之不显示。

4、
搜索Context.HDMI_SERVICE看它是在什么地方被放入ServiceManager的,显然这个操作应该是framework级别的,所以为了提高搜索精度我们可以这么写:

  1. $ grep "Context.HDMI_SERVICE" -nrw frameworks/

搜索结果如下:

  1. frameworks/base/services/java/com/android/server/SystemServer.java:1357: ServiceManager.addService(Context.HDMI_SERVICE,
  2. frameworks/base/services/core/java/com/android/server/display/WifiDisplayController.java:447: .getService(Context.HDMI_SERVICE));

5、
打开SystemServer.java查看 1357行附近的代码:

  1. /**
  2. * Starts a miscellaneous grab bag of stuff that has yet to be refactored
  3. * and organized.
  4. */
  5. private void startOtherServices() {
  6. /// 此处省略大量代码
  7. /// M: add for HDMI feature @{
  8. /// 满足这个 if 条件就执行下面的 add 操作
  9. if (!disableNonCoreServices
  10. && SystemProperties.get("ro.mtk_hdmi_support").equals("1")) {
  11. try {
  12. Slog.i(TAG, "HDMI Manager Service");
  13. /// 实例化 MtkHdmiManagerService 对象
  14. hdmiManager = new MtkHdmiManagerService(context);
  15. /// 对象绑定
  16. ServiceManager.addService(Context.HDMI_SERVICE,
  17. hdmiManager.asBinder());
  18. } catch (Throwable e) {
  19. Slog.e(TAG, "Failure starting MtkHdmiManager", e);
  20. }
  21. }
  22. /// @}
  23. /// 此处又省略大量代码
  24. }

到这里 if 条件里面的ro.mtk_hdmi_support就是关键了,它一般就直接和宏开关有联系了。

6、
搜索ro.mtk_hdmi_support,因宏开关一般都在device目录下,同样为了提高搜索精度,我们这么写:

  1. $ grep "ro.mtk_hdmi_support" -nrw device/

搜索结果如下:

  1. 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行左右的代码:

  1. ifeq ($(strip $(MTK_HDMI_SUPPORT)), yes)
  2. PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_support=1
  3. endif

到这里宏开关MTK_HDMI_SUPPORT就暴露出来了。接下来就可以按前面介绍的步骤去关闭相应的宏开关了。

实际在 device/mediatek/common/device.mk 可能找到多出 HDMI 相关的宏定义,如下:

  1. ifeq ($(strip $(MTK_HDMI_SUPPORT)), yes)
  2. PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_support=1
  3. endif
  4. ifeq ($(strip $(MTK_MT8193_HDMI_SUPPORT)), yes)
  5. PRODUCT_PROPERTY_OVERRIDES += ro.mtk_mt8193_hdmi_support=1
  6. endif
  7. ifeq ($(strip $(MTK_HDMI_HDCP_SUPPORT)), yes)
  8. PRODUCT_PROPERTY_OVERRIDES += ro.mtk_hdmi_hdcp_support=1
  9. endif
  10. ifeq ($(strip $(MTK_INTERNAL_HDMI_SUPPORT)), yes)
  11. PRODUCT_PROPERTY_OVERRIDES += ro.mtk_internal_hdmi_support=1
  12. endif

它们分别是做什么的,我们也不知道,但可以确定的是和 HDMI 相关,如果要彻底屏蔽 HDMI 功能,不妨将他们都关掉。