RK3399 Android系统 添加特殊HDMI分辨率
2020-08-17 17:47:38
ThanksView
  • 访问次数: 222
  • 注册日期: 2019-03-19
  • 最后登录: 2024-04-22

一、Android修改
    1、文件AndroidManifest.xml
    位置:packages\apps\Settings\AndroidManifest.xml
    找到以下内容:
            <!-- HDMI -->
            <activity android:name="Settings$HdmiSettingsActivity"
                    android:label="@string/hdmi"
                    android:taskAffinity="">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.VOICE_LAUNCH" />
                    <category android:name="com.android.settings.SHORTCUT" />
                </intent-filter>
                <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                    android:value="com.android.settings.HdmiSettings" />
                <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                    android:value="true" />
            </activity>
           
            <receiver android:name="HdmiReceiver">
                <intent-filter android:priority="1000">
                    <action android:name="android.intent.action.HDMI_PLUG"/>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                </intent-filter>
           </receiver>
    修改为以下内容:
            <!-- HDMI -->
            <activity android:name="Settings$HdmiSettingsActivity"
                    android:label="@string/hdmi"               
                    android:icon="@drawable/ic_settings_hdmi"
                    android:taskAffinity="com.android.settings"
                    android:parentActivityName="Settings">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.VOICE_LAUNCH" />
                    <category android:name="com.android.settings.SHORTCUT" />
                </intent-filter>
                <intent-filter android:priority="8">
                    <action android:name="com.android.settings.action.SETTINGS" />
                </intent-filter>
                <meta-data android:name="com.android.settings.category"
                    android:value="com.android.settings.category.device" />
                <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                    android:value="com.android.settings.HdmiSettings" />
                <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                    android:value="true" />
            </activity>
           
            <receiver android:name="HdmiReceiver">
                <intent-filter android:priority="1000">
                    <action android:name="android.intent.action.HDMI_PLUG"/>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                </intent-filter>
           </receiver>

    2、文件DisplaySettings.java
    位置:packages\apps\Settings\src\com\android\settings\DisplaySettings.java
    找到以下内容:
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            mProduct = SystemProperties.get("ro.target.product");
            String supportHDMI = SystemProperties.get("ro.rk.hdmi_enable", "false");
            final Activity activity = getActivity();
            final ContentResolver resolver = activity.getContentResolver();

            addPreferencesFromResource(R.xml.display_settings);
            mHDMIPreference = findPreference(KEY_HDMI_SETTINGS);
            if(!"tablet".equals(mProduct) || !"true".equals(supportHDMI)){
                getPreferenceScreen().removePreference(mHDMIPreference);
            }
    修改为以下内容:
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            mProduct = SystemProperties.get("ro.target.product");
            String supportHDMI = SystemProperties.get("ro.rk.hdmi_enable", "false");
            final Activity activity = getActivity();
            final ContentResolver resolver = activity.getContentResolver();

            addPreferencesFromResource(R.xml.display_settings);
            mHDMIPreference = findPreference(KEY_HDMI_SETTINGS);
            if("tablet".equals(mProduct) || "true".equals(supportHDMI)){
                getPreferenceScreen().removePreference(mHDMIPreference);
            }

    3、文件HdmiSettings.java
    位置:packages\apps\Settings\src\com\android\settings\HdmiSettings.java
    找到以下内容:
        import android.hardware.display.DisplayManager;
        import android.view.Display;

        import android.view.IWindowManager;
        import android.view.Surface;
        import android.os.ServiceManager;

        public class HdmiSettings extends SettingsPreferenceFragment
                implements OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Preference.OnPreferenceClickListener {
            /**
             * Called when the activity is first created.
             */
            private static final String TAG = "HdmiSettings";
            private static final String KEY_HDMI_RESOLUTION = "hdmi_resolution";
            private static final String KEY_HDMI_SCALE = "hdmi_screen_zoom";
            private static final String KEY_HDMI_ROTATION="hdmi_rotation";
    修改为以下内容:
        import android.hardware.display.DisplayManager;
        import android.view.Display;

        public class HdmiSettings extends SettingsPreferenceFragment
                implements OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Preference.OnPreferenceClickListener {
            /**
             * Called when the activity is first created.
             */
            private static final String TAG = "HdmiSettings";
            private static final String KEY_HDMI_RESOLUTION = "hdmi_resolution";
            private static final String KEY_HDMI_SCALE = "hdmi_screen_zoom";

    再找到以下内容:
        private ListPreference mHdmiResolution;
        private ListPreference mHdmiRotation;
        private Preference mHdmiScale;
    修改为以下内容:
        private ListPreference mHdmiResolution;
        private Preference mHdmiScale;

    再找到以下内容:
        private DisplayManager mDisplayManager;
        private DisplayListener mDisplayListener;
        private IWindowManager wm;
    修改为以下内容:
        private DisplayManager mDisplayManager;
        private DisplayListener mDisplayListener;

    再找到以下内容:
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            IntentFilter filter = new IntentFilter("android.intent.action.HDMI_PLUGGED");
            getContext().registerReceiver(HdmiListener, filter);
            context = getActivity();
            mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
            mDisplayListener = new DisplayListener();
            mStrPlatform = SystemProperties.get("ro.board.platform");
            mDisplayInfo = getDisplayInfo();
            addPreferencesFromResource(R.xml.hdmi_settings_timeout);
            mHdmiResolution = (ListPreference) findPreference(KEY_HDMI_RESOLUTION);
            mHdmiResolution.setOnPreferenceChangeListener(this);
            mHdmiResolution.setOnPreferenceClickListener(this);
            if (mDisplayInfo != null) {
                mHdmiResolution.setEntries(DrmDisplaySetting.getDisplayModes(mDisplayInfo).toArray(new String[0]));
                mHdmiResolution.setEntryValues(DrmDisplaySetting.getDisplayModes(mDisplayInfo).toArray(new String[0]));
            }
            mHdmiScale = findPreference(KEY_HDMI_SCALE);
            mHdmiScale.setOnPreferenceClickListener(this);
            mHdmiRotation = (ListPreference) findPreference(KEY_HDMI_ROTATION);
            mHdmiRotation.setOnPreferenceChangeListener(this);
            init();
            Log.d(TAG, "onCreate---------------------");
        }
    修改为以下内容:
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            IntentFilter filter = new IntentFilter("android.intent.action.HDMI_PLUGGED");
            getContext().registerReceiver(HdmiListener, filter);
            context = getActivity();
            mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
            mDisplayListener = new DisplayListener();
            mStrPlatform = SystemProperties.get("ro.board.platform");
            addPreferencesFromResource(R.xml.hdmi_settings);
            mHdmiResolution = (ListPreference) findPreference(KEY_HDMI_RESOLUTION);
            mHdmiResolution.setOnPreferenceChangeListener(this);
            mHdmiResolution.setOnPreferenceClickListener(this);
            mHdmiScale = findPreference(KEY_HDMI_SCALE);
            mHdmiScale.setOnPreferenceClickListener(this);
            init();
            Log.d(TAG, "onCreate---------------------");
        }

    再找到以下内容:
        private void init() {
            mIsUseDisplayd = SystemProperties.getBoolean("ro.rk.displayd.enable", false);

            //init hdmi rotation
            try {
                 wm = IWindowManager.Stub.asInterface(
                      ServiceManager.getService(Context.WINDOW_SERVICE));
                 int rotation = wm.getRotation();
                 switch (rotation) {
                      case Surface.ROTATION_0:
                           mHdmiRotation.setValue("0");
                           break;
                      case Surface.ROTATION_90:
                           mHdmiRotation.setValue("90");
                           break;
                      case Surface.ROTATION_180:
                           mHdmiRotation.setValue("180");
                           break;
                      case Surface.ROTATION_270:
                           mHdmiRotation.setValue("270");
                           break;
                      default:
                           mHdmiRotation.setValue("0");
                    }
                } catch (Exception e) {
                    Log.e(TAG, e.toString());
                }
        }
    修改为以下内容:
        private void init() {
            mIsUseDisplayd = SystemProperties.getBoolean("ro.rk.displayd.enable", false);
        }

    再找到以下内容:
        public void updateResolutionValue() {
            String resolutionValue = null;
            mDisplayInfo = getDisplayInfo();
            if (mDisplayInfo != null)
                resolutionValue = DrmDisplaySetting.getCurDisplayMode(mDisplayInfo);
            Log.i(TAG, "resolutionValue:" + resolutionValue);
            mOldResolution = resolutionValue;
            if (resolutionValue != null)
                mHdmiResolution.setValue(resolutionValue);
        }
    修改为以下内容:
        public void updateResolutionValue() {
            String resolutionValue = null;
            mDisplayInfo = getDisplayInfo();
            if (mDisplayInfo != null)
                resolutionValue = DrmDisplaySetting.getCurDisplayMode(mDisplayInfo);
            Log.i(TAG, "resolutionValue:" + resolutionValue);       
            mOldResolution = resolutionValue;
            if (resolutionValue != null) {     
                int index = getEntryValueIndex(resolutionValue); 
                if (index != -1) { 
                    mHdmiResolution.setValueIndex(index);
                }
            }
        }

    再找到以下内容:
        private void updateHDMIState() {
            Display[] allDisplays = mDisplayManager.getDisplays();
            String switchValue = SystemProperties.get("sys.hdmi_status.aux", "on");
            if (allDisplays == null || allDisplays.length < 2 || switchValue.equals("off")) {
                mHdmiResolution.setEnabled(false);
                mHdmiScale.setEnabled(false);
                mHdmiRotation.setEnabled(false);
            } else {
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        mDisplayInfo = getDisplayInfo();
                        //增加延迟,保证数据能够拿到
                        if (mDisplayInfo != null) {
                            mHdmiResolution.setEntries(DrmDisplaySetting.getDisplayModes(mDisplayInfo).toArray(new String[0]));
                            mHdmiResolution.setEntryValues(DrmDisplaySetting.getDisplayModes(mDisplayInfo).toArray(new String[0]));
                            updateResolutionValue();
                            mHdmiResolution.setEnabled(true);
                            mHdmiScale.setEnabled(true);
                            mHdmiRotation.setEnabled(true);
                        }

                    }
                }, 1000);
            }
        }
    修改为以下内容:
        private void updateHDMIState() {
            String switchValue = SystemProperties.get("sys.hdmi_status.aux", "on");
            if (switchValue.equals("off")) {
                mHdmiResolution.setEnabled(false);
                mHdmiScale.setEnabled(false);
            } else {
                mHdmiResolution.setEnabled(true);
                mHdmiScale.setEnabled(true);
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        mDisplayInfo = getDisplayInfo();
                        //增加延迟,保证数据能够拿到
                        if (mDisplayInfo != null) {
                            updateResolutionValue();
                        }
                    }
                }, 1000);
            }
        }

    再找到以下内容:
    @Override
    public boolean onPreferenceClick(Preference preference) {
        if (preference == mHdmiScale) {
            Intent screenScaleIntent = new Intent(getActivity(), ScreenScaleActivity.class);
            screenScaleIntent.putExtra(ConstData.IntentKey.PLATFORM, mStrPlatform);
            mDisplayInfo = getDisplayInfo();
            if (mDisplayInfo != null) {
                screenScaleIntent.putExtra(ConstData.IntentKey.DISPLAY_INFO, mDisplayInfo);
                startActivity(screenScaleIntent);
            }
        } else if (preference == mHdmiResolution) {
            updateHDMIState();
        }
        return true;
    }
    后面新增以下内容:
    private int getDisplayModeIndex(String mode) {
        int index = 0;
        mDisplayInfo = getDisplayInfo();
        if (mDisplayInfo != null) {
            // 完全匹配(分辨率+刷新率)
            index = 0;
            for (String entrymode : DrmDisplaySetting.getDisplayModes(mDisplayInfo)) {
                if (entrymode.toLowerCase().startsWith(mode.toLowerCase())) {
                    return index;
                }
                index += 1;
            }
            // 部分匹配(分辨率)
            index = 0;
            mode = mode.substring(0, mode.length()-2);
            for (String entrymode : DrmDisplaySetting.getDisplayModes(mDisplayInfo)) {
                if (entrymode.toLowerCase().startsWith(mode.toLowerCase())) {
                    return index;
                }
                index += 1;
            }
        }
        return -1;
    }

    private int getEntryValueIndex(String resolutionValue) {
        // 完全匹配(分辨率+刷新率)
        int index = 0;
        for (CharSequence entryval : mHdmiResolution.getEntryValues()) {
            String entryvalue = entryval.toString();
            if (resolutionValue.toLowerCase().startsWith(entryvalue.toLowerCase())) {
                return index;
            }
            index += 1;
        }      
        // 部分匹配(分辨率)
        index = 0;
        for (CharSequence entryval : mHdmiResolution.getEntryValues()) {
            String entryvalue = entryval.toString();
            entryvalue = entryvalue.substring(0, entryvalue.length()-2);
            if (resolutionValue.toLowerCase().startsWith(entryvalue.toLowerCase())) {
                return index;
            }
            index += 1;
        } 
        return -1;
    }

    再找到以下内容:
        @Override
        public boolean onPreferenceChange(Preference preference, Object obj) {
            Log.i(TAG, "onPreferenceChange:" + obj);
            String key = preference.getKey();
            Log.d(TAG, key);
            if (KEY_HDMI_RESOLUTION.equals(key)) {
                if (obj.equals(mOldResolution))
                    return true;
                int index = mHdmiResolution.findIndexOfValue((String) obj);
                Log.i(TAG, "onPreferenceChange: index= " + index);
                mDisplayInfo = getDisplayInfo();
                if (mDisplayInfo != null) {
                    DrmDisplaySetting.setDisplayModeTemp(mDisplayInfo, index);
                    showConfirmSetModeDialog();
                }
            }
            if (KEY_HDMI_ROTATION.equals(key)) {
                try {
                    int value = Integer.parseInt((String) obj);
                    android.os.SystemProperties.set("persist.sys.orientation", (String) obj);
                    Log.d(TAG,"freezeRotation~~~value:"+(String) obj);
                    if(value == 0)
                          wm.freezeRotation(Surface.ROTATION_0);
                    else if(value == 90)
                          wm.freezeRotation(Surface.ROTATION_90);
                    else if(value == 180)
                          wm.freezeRotation(Surface.ROTATION_180);
                    else if(value == 270)
                          wm.freezeRotation(Surface.ROTATION_270);
                    else
                          return true;
                    //android.os.SystemProperties.set("sys.boot_completed", "1");
                 } catch (Exception e) {
                          Log.e(TAG, "freezeRotation error");
                 }
             }
            return true;
        }
    修改为以下内容:
        @Override
        public boolean onPreferenceChange(Preference preference, Object obj) {
            Log.i(TAG, "onPreferenceChange:" + obj);
            String key = preference.getKey();
            Log.d(TAG, key);
            if (KEY_HDMI_RESOLUTION.equals(key)) {
                if (obj.equals(mOldResolution))
                    return true;
                int index = mHdmiResolution.findIndexOfValue((String) obj);
                String mode = (String) obj;
                Log.i(TAG, "onPreferenceChange: index= " + index + ", mode= " + mode);
                mDisplayInfo = getDisplayInfo();
                Log.i(TAG, "DisplayInfo ==> " + mDisplayInfo.toString());
                if (mDisplayInfo != null) {
                    index = getDisplayModeIndex(mode);
                    if (index != -1) {
                        DrmDisplaySetting.setDisplayModeTemp(mDisplayInfo, index);
                    } else {
                        DrmDisplaySetting.setDisplayModeTemp(mDisplayInfo, mode);
                    }             
                }
            }
            return true;
        }

    4、文件arrays.xml
    位置:packages\apps\Settings\res\values\arrays.xml
    找到以下内容:
        <!-- HDMI -->
        <string-array name="hdmi_resolution_entries">
            <item>1920x1080p-50Hz </item>
            <item>1920x1080p-60Hz</item>
            <item>1280x720p-50Hz</item>
            <item>1280x720p-60Hz</item>
            <item>720x576p-50Hz </item>
            <item>720x480p-60Hz </item>
        </string-array>
        <string-array name="hdmi_resolution_values">
            <item>1920x1080p-50\n</item>
            <item>1920x1080p-60\n</item>
            <item>1280x720p-50\n</item>
            <item>1280x720p-60\n</item>
            <item>720x576p-50\n</item>
            <item>720x480p-60\n</item>
        </string-array>
    修改为以下内容:
        <!-- HDMI -->
        <string-array name="hdmi_resolution_entries">
            <item>1920x1080p-50Hz </item>
            <item>1920x1080p-60Hz</item>
            <item>1366x768p-60Hz</item>
            <item>1280x800p-60Hz</item>
            <item>1280x720p-60Hz</item>
            <item>1024x768p-60Hz</item>
        </string-array>
        <string-array name="hdmi_resolution_values">
            <item>1920x1080p50\n</item>
            <item>1920x1080p60\n</item>
            <item>1366x768p60\n</item>
            <item>1280x800p60\n</item>
            <item>1280x720p60\n</item>
            <item>1024x768p60\n</item>
        </string-array>

    5、文件resolution_white.xml
    位置:device\rockchip\common\resolution_white.xml
    找到最后一行:
    </resolutions>
    在它前面一行新增以下内容:
        <resolution>
            <clock>85500</clock>
            <hdisplay>1366</hdisplay>
            <hsync_start>1436</hsync_start>
      <hsync_end>1579</hsync_end>
      <htotal>1792</htotal>
      <hskew>0</hskew>
      <vdisplay>768</vdisplay>
      <vsync_start>771</vsync_start>
      <vsync_end>777</vsync_end>
      <vtotal>798</vtotal>
      <vscan>0</vscan>
      <vrefresh>60</vrefresh>
      <flags>5</flags>
      <vic>108</vic>
        </resolution>
        <resolution>
            <clock>71000</clock>
            <hdisplay>1280</hdisplay>
            <hsync_start>1328</hsync_start>
      <hsync_end>1360</hsync_end>
      <htotal>1440</htotal>
      <hskew>0</hskew>
      <vdisplay>800</vdisplay>
      <vsync_start>803</vsync_start>
      <vsync_end>809</vsync_end>
      <vtotal>823</vtotal>
      <vscan>0</vscan>
      <vrefresh>60</vrefresh>
      <flags>9</flags>
      <vic>109</vic>
        </resolution>
        <resolution>
            <clock>65000</clock>
            <hdisplay>1024</hdisplay>
            <hsync_start>1048</hsync_start>
      <hsync_end>1184</hsync_end>
      <htotal>1344</htotal>
      <hskew>0</hskew>
      <vdisplay>768</vdisplay>
      <vsync_start>771</vsync_start>
      <vsync_end>777</vsync_end>
      <vtotal>806</vtotal>
      <vscan>0</vscan>
      <vrefresh>60</vrefresh>
      <flags>A</flags>
      <vic>110</vic>
        </resolution>

二、 Kernel修改
    1、文件rockchip-hdmi.h
    位置:kernel\drivers\video\rockchip\hdmi\rockchip-hdmi.h
    找到以下内容:
    /* HDMI video information code according CEA-861-F */
    enum hdmi_video_information_code {
    ......
     HDMI_3840X2160P_24HZ_21_9,
     HDMI_3840X2160P_25HZ_21_9,
     HDMI_3840X2160P_30HZ_21_9, /*105*/
     HDMI_3840X2160P_50HZ_21_9,
     HDMI_3840X2160P_60HZ_21_9,
    在后面新增以下内容:
     HDMI_1366X768P_60HZ,
     HDMI_1280X800P_60HZ,
     HDMI_1024X768P_60HZ,  /*110*/

    2、文件rockchip-hdmi-lcdc.c
    位置:kernel\drivers\video\rockchip\hdmi\rockchip-hdmi-lcdc.c
    找到以下内容:
    static const struct hdmi_video_timing hdmi_mode[] = {
    ......
     {
      .mode = {
       .name = " 1024x768p@60Hz",
       .refresh = 60,
       .xres = 1024,
       .yres = 768,
       .pixclock = 65000000,
       .left_margin = 160,
       .right_margin = 24,
       .upper_margin = 29,
       .lower_margin = 3,
       .hsync_len = 136,
       .vsync_len = 6,
       .sync = 0,
       .vmode = 0,
       .flag = 0,
      },
      .vic = HDMI_VIDEO_DMT | 2,
      .vic_2nd = 0,
      .pixelrepeat = 1,
      .interface = OUT_P888,
     },
    后面新增以下内容:
     {
      .mode = {
       .name = " 1280x800p@60Hz",
       .refresh = 60,
       .xres = 1280,
       .yres = 800,
       .pixclock = 71000000,
       .left_margin = 80,
       .right_margin = 48,
       .upper_margin = 14,
       .lower_margin = 3,
       .hsync_len = 136,
       .vsync_len = 6,
       .sync = 0,
       .vmode = 0,
       .flag = 0,
      },
      .vic = HDMI_1280X800P_60HZ,
      .vic_2nd = 0,
      .pixelrepeat = 1,
      .interface = OUT_P888,
     },

三、编译

三维半岛官网: http://www.thanksview.com

进入首页