最近到4412最基本的都调了 然后觉得没事做了 所以增加一个HDMI的设置 不能闲着
以下使用的是广州斯道的icool210开发板 源码修改如下
最开始我是先在设置里加上这些设置然后在去实现功能 这里就一起说了 之前android2.3里有HDMI设置所以这里就参照那个增加 首先修改Setting
查看libhdmi库首先查看下hdmi能设置的格式 源码路径
device/samsung/common/s5p/libhdmi/SecHdmi.cpp
你会发现有如下代码
mHdmiResolutionValueList[0] = 1080960;
mHdmiResolutionValueList[1] = 1080950;
mHdmiResolutionValueList[2] = 1080930;
mHdmiResolutionValueList[3] = 1080160;
mHdmiResolutionValueList[4] = 1080150;
mHdmiResolutionValueList[5] = 720960;
mHdmiResolutionValueList[6] = 720950;
mHdmiResolutionValueList[7] = 5769501;
mHdmiResolutionValueList[8] = 5769502;
mHdmiResolutionValueList[9] = 4809601;
mHdmiResolutionValueList[10] = 4809602;
ResolutionValue根据这个我们大致知道了支持了格式 下面来修改Setting
源码路径 packages/apps/Settings/res/values/arrays.xml
增加如下代码
<!-- TV Out settings. -->
<string-array name="tv_resolution_entries">
<item>1080P_60</item>
<item>1080P_50</item>
<item>1080P_30</item>
<item>1080I_60</item>
<item>1080I_50</item>
<item>720P_60</item>
<item>720P_50</item>
<item>576P_50_16_9</item>
<item>576P_50_4_3</item>
<item>480P_60_16_9</item>
<item>480P_60_4_3</item>
</string-array>
<!-- Do not translate. -->
<string-array name="tv_resolution_values" translatable="false">
<!-- Do not translate. -->
<item>1080960</item>
<!-- Do not translate. -->
<item>1080950</item>
<!-- Do not translate. -->
<item>1080930</item>
<!-- Do not translate. -->
<item>1080160</item>
<!-- Do not translate. -->
<item>1080150</item>
<!-- Do not translate. -->
<item>720960</item>
<!-- Do not translate. -->
<item>720950</item>
<!-- Do not translate. -->
<item>5769501</item>
<!-- Do not translate. -->
<item>5769502</item>
<!-- Do not translate. -->
<item>4809601</item>
<!-- Do not translate. -->
<item>4809602</item>
</string-array>
<!-- TV Out settings. -->
<string-array name="tv_hdcp_entries">
<item>Disable</item>
<item>Enable</item>
</string-array>
<!-- Do not translate. -->
<string-array name="tv_hdcp_values" translatable="false">
<!-- Do not translate. -->
<item>0</item>
<!-- Do not translate. -->
<item>1</item>
</string-array>
<!-- TV Out settings. -->
<string-array name="tv_mode_entries">
<item>HDMI(YCbCr)</item>
<item>HDMI(RGB)</item>
<item>DVI</item>
</string-array>
<!-- Do not translate. -->
<string-array name="tv_mode_values" translatable="false">
<!-- Do not translate. -->
<item>0</item>
<!-- Do not translate. -->
<item>1</item>
<!-- Do not translate. -->
<item>2</item>
</string-array>
源码路径 packages/apps/Settings/res/values/strings.xml
增加如下内容
<!-- Sound & display settings screen, setting option name to change TV Mode -->
<string name="tv_mode">TV Mode</string>
<!-- Sound & display settings screen, setting option summary to change TV Mode -->
<string name="tv_mode_summary">Choose TV out mode</string>
<!-- Sound & display settings screen, setting option name to change TV Resolution -->
<string name="tv_resolution">TV Resolution</string>
<!-- Sound & display settings screen, setting option summary to change TV Resolution -->
<string name="tv_resolution_summary">Choose TV resolution</string>
<!-- Sound & display settings screen, setting option name to change TV HDCP -->
<string name="tv_hdcp">TV HDCP</string>
<!-- Sound & display settings screen, setting option summary to change TV HDCP -->
<string name="tv_hdcp_summary">Enable HDMI HDCP</string>
源码路径 packages/apps/Settings/res/xml/display_settings.xml
增加如下内容
<ListPreference
android:key="tv_mode"
android:title="@string/tv_mode"
android:summary="@string/tv_mode_summary"
android:persistent="false"
android:entries="@array/tv_mode_entries"
android:entryValues="@array/tv_mode_values" />
<ListPreference
android:key="tv_resolution"
android:title="@string/tv_resolution"
android:summary="@string/tv_resolution_summary"
android:persistent="false"
android:entries="@array/tv_resolution_entries"
android:entryValues="@array/tv_resolution_values" />
<ListPreference
android:key="tv_hdcp"
android:title="@string/tv_hdcp"
android:summary="@string/tv_hdcp_summary"
android:persistent="false"
android:entries="@array/tv_hdcp_entries"
android:entryValues="@array/tv_hdcp_values" />
接着修改
framework
源码路径:frameworks/base/core/java/android/provider/Settings.java
增加如下内容:
/**
* The tv out mode.
*/
public static final String TV_MODE = "tv_mode";
/**
* The tv out resolution.
*/
public static final String TV_RESOLUTION = "tv_resolution";
/**
* The tv out mode.
*/
public static final String TV_HDCP = "tv_hdcp";
接着在这个文件里搜所SCREEN_OFF_TIMEOUT
会在public static final String[] SETTINGS_TO_BACKUP这个数组里找到一个 然后在它下面增加如下
TV_MODE,
TV_RESOLUTION,
TV_HDCP,
按照我的理解这里应该是用来保存数据到数据库的 然后系统再次启动后设置还能保存
接着增加调用hdmi相关函数的接口 这里我是直接把2.3的拷过来然后进行的修改
创建相应目录增加以下文件frameworks/base/slsi/java/com/slsi/sec/android/HdmiService.java
内容如下
package com.slsi.sec.android;
public class HdmiService
{
static {
System.loadLibrary("hdmiservice_jni");
}
public native void setHdmiCableStatus(int status);
public native void setHdmiMode(int mode);
public native void setHdmiResolution(int resolution);
public native void setHdmiHdcp(int enHdcp);
public native void initHdmiService();
}
增加以下文件frameworks/base/slsi/jni/Android.mk
内容如下
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
com_slsi_sec_android_HdmiService.cpp \
onload.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
libcutils \
libandroid_runtime \
libnativehelper
ifeq ($(S5P_BOARD_USES_HDMI),true)
LOCAL_C_INCLUDES += \
device/samsung/common/s5p/libhdmi
LOCAL_SHARED_LIBRARIES += libhdmiclient
LOCAL_CFLAGS += -DBOARD_USES_HDMI
endif
LOCAL_PRELINK_MODULE := false
ifeq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_OS),linux)
ifeq ($(TARGET_ARCH),x86)
LOCAL_LDLIBS += -lpthread -ldl -lrt
endif
endif
endif
ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
endif
LOCAL_MODULE_TAGS := optional eng
LOCAL_MODULE:= libhdmiservice_jni
include $(BUILD_SHARED_LIBRARY)
增加以下文件frameworks/base/slsi/jni/com_slsi_sec_android_HdmiService.cpp
内容如下
#define LOG_TAG "HDMIStatusService"
#include "jni.h"
#include "JNIHelp.h"
#include <cutils/log.h>
#if defined(BOARD_USES_HDMI)
#include "SecHdmiClient.h"
#endif
namespace android {
/*
* Class: com_slsi_sec_android_HdmiService
* Method: setHdmiCableStatus
* Signature: (I)V
*/
static void com_slsi_sec_android_HdmiService_setHdmiCableStatus
(JNIEnv *env, jobject obj, jint i)
{
int result = 0;
#if defined(BOARD_USES_HDMI)
//LOGD("%s HDMI status: %d", __func__, i);
(SecHdmiClient::getInstance())->setHdmiCableStatus(i);
#else
return;
#endif
//return result;
}
/*
* Class: com_slsi_sec_android_setHdmiMode
* Method: setHdmiMode
* Signature: (I)V
*/
static void com_slsi_sec_android_HdmiService_setHdmiMode
(JNIEnv *env, jobject obj, jint i)
{
int result = 0;
#if defined(BOARD_USES_HDMI)
(SecHdmiClient::getInstance())->setHdmiMode(i);
#else
return;
#endif
}
/*
* Class: com_slsi_sec_android_setHdmiResolution
* Method: setHdmiResolution
* Signature: (I)V
*/
static void com_slsi_sec_android_HdmiService_setHdmiResolution
(JNIEnv *env, jobject obj, jint i)
{
int result = 0;
#if defined(BOARD_USES_HDMI)
(SecHdmiClient::getInstance())->setHdmiResolution(i);
#else
return;
#endif
}
/*
* Class: com_slsi_sec_android_setHdmiHdcp
* Method: setHdmiHdcp
* Signature: (I)V
*/
static void com_slsi_sec_android_HdmiService_setHdmiHdcp
(JNIEnv *env, jobject obj, jint i)
{
int result = 0;
#if defined(BOARD_USES_HDMI)
(SecHdmiClient::getInstance())->setHdmiHdcp(i);
#else
return;
#endif
}
/*
* Class: com_slsi_sec_android_HdmiService
* Method: initHdmiService
* Signature: ()V
*/
static void com_slsi_sec_android_HdmiService_initHdmiService
(JNIEnv *env, jobject obj)
{
#if defined(BOARD_USES_HDMI)
LOGI("%s ", __func__);
//(SecHdmiClient::getInstance())->init();
#else
return;
#endif
//return result;
}
static JNINativeMethod gMethods[] = {
{"setHdmiCableStatus", "(I)V", (void*)com_slsi_sec_android_HdmiService_setHdmiCableStatus},
{"setHdmiMode", "(I)V", (void*)com_slsi_sec_android_HdmiService_setHdmiMode},
{"setHdmiResolution", "(I)V", (void*)com_slsi_sec_android_HdmiService_setHdmiResolution},
{"setHdmiHdcp", "(I)V", (void*)com_slsi_sec_android_HdmiService_setHdmiHdcp},
{"initHdmiService", "()V", (void*)com_slsi_sec_android_HdmiService_initHdmiService},
};
int register_com_samsung_sec_android_HdmiService(JNIEnv* env)
{
jclass clazz = env->FindClass("com/slsi/sec/android/HdmiService");
if (clazz == NULL)
{
LOGE("Can't find com/slsi/sec/android/HdmiService");
return -1;
}
return jniRegisterNativeMethods(env, "com/slsi/sec/android/HdmiService",
gMethods, NELEM(gMethods));
}
} /* namespace android */
增加如下文件:frameworks/base/slsi/jni/onload.cpp
内容如下
#include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"
namespace android {
int register_com_samsung_sec_android_HdmiService(JNIEnv* env);
};
using namespace android;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("GetEnv failed!");
return result;
}
LOG_ASSERT(env, "Could not retrieve the env!");
if(register_com_samsung_sec_android_HdmiService(env) == -1)
LOGE("%s register_com_samsung_sec_android_HdmiStatus is failed", __func__);
return JNI_VERSION_1_4;
}
然后修改build/core/pathmap.mk
在FRAMEWORKS_BASE_SUBDIRS里增加slsi \
我们要让他启动的时候能能自动设置成设置的参数所以
接着修改frameworks/base/services/java/com/android/server/SystemServer.java
增加如下内容
import com.slsi.sec.android.HdmiService;
import static android.provider.Settings.System.TV_MODE;
import static android.provider.Settings.System.TV_RESOLUTION;
import static android.provider.Settings.System.TV_HDCP;
private HdmiService mHdmiService;
然后在
mContentResolver = context.getContentResolver();
之后增加如下代码
Slog.i(TAG, "HDMI Setting");
mHdmiService = new HdmiService();
mHdmiService.setHdmiMode(Settings.System.getInt(mContentResolver, TV_MODE, 0));
mHdmiService.setHdmiResolution(Settings.System.getInt(mContentResolver, TV_RESOLUTION, 4809601));
mHdmiService.setHdmiHdcp(Settings.System.getInt(mContentResolver, TV_HDCP, 0));
跟着最后修改Setting里的DisplaySetting
源码路径packages/apps/Settings/src/com/android/settings/DisplaySettings.java
增加如下内容
import com.slsi.sec.android.HdmiService;
import static android.provider.Settings.System.TV_MODE;
import static android.provider.Settings.System.TV_RESOLUTION;
import static android.provider.Settings.System.TV_HDCP;
private static final String KEY_TV_MODE = "tv_mode";
private static final String KEY_TV_RESOLUTION = "tv_resolution";
private static final String KEY_TV_HDCP = "tv_hdcp";
private static final int FALLBACK_TV_MODE_VALUE = 0;
private static final int FALLBACK_TV_RESOLUTION_VALUE = 4809601;
private static final int FALLBACK_TV_HDCP_VALUE = 0;
private HdmiService mHdmiService;
然后在onCreate增加如下代码
ListPreference tvModePreference =
(ListPreference) findPreference(KEY_TV_MODE);
tvModePreference.setValue(String.valueOf(Settings.System.getInt(
resolver, TV_MODE, FALLBACK_TV_MODE_VALUE)));
tvModePreference.setOnPreferenceChangeListener(this);
ListPreference tvResolutionPreference =
(ListPreference) findPreference(KEY_TV_RESOLUTION);
tvResolutionPreference.setValue(String.valueOf(Settings.System.getInt(
resolver, TV_RESOLUTION, FALLBACK_TV_RESOLUTION_VALUE)));
tvResolutionPreference.setOnPreferenceChangeListener(this);
ListPreference tvHdcpPreference =
(ListPreference) findPreference(KEY_TV_HDCP);
tvHdcpPreference.setValue(String.valueOf(Settings.System.getInt(
resolver, TV_HDCP, FALLBACK_TV_HDCP_VALUE)));
tvHdcpPreference.setOnPreferenceChangeListener(this);
mHdmiService = new HdmiService();
接着在onPreferenceChange函数里增加如下内容
if (KEY_TV_MODE.equals(key)) {
int value = Integer.parseInt((String) objValue);
try {
Settings.System.putInt(getContentResolver(),
TV_MODE, value);
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist tv mode setting", e);
}
mHdmiService.setHdmiMode(value);
}
if (KEY_TV_RESOLUTION.equals(key)) {
int value = Integer.parseInt((String) objValue);
try {
Settings.System.putInt(getContentResolver(),
TV_RESOLUTION, value);
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist tv resolution setting", e);
}
mHdmiService.setHdmiResolution(value);
}if (KEY_TV_HDCP.equals(key)) {
int value = Integer.parseInt((String) objValue);
try {
Settings.System.putInt(getContentResolver(),
TV_HDCP, value);
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist tv resolution setting", e);
}
mHdmiService.setHdmiHdcp(value);
}
基本上就搞定了 最后如图所示
相关patch我也上传到了我的资源 不知道为啥没显示出来 需要的可以去下载