安卓11-设置HDMI分辨率流程

安卓11中从设置-显示设置hdmi分辨率流程:framework层通过jni控制底层驱动实现,标准驱动模型


packages\apps\Settings\src\com\android\settings\display\HdmiSettings.java
     private void updateResolution(final ITEM_CONTROL control, final int index) {
        showWaitingDialog(R.string.dialog_update_resolution);
        mEnableDisplayListener = false;
        new Thread() {
            @Override
            public void run() {
                if (ITEM_CONTROL.CHANGE_RESOLUTION == control) {
                    synchronized (mLock) {
                        int display = mSelectDisplayInfo.getDisplayNo();
                        DrmDisplaySetting.updateDisplayInfos();
                        DrmDisplaySetting.updateDisplayModesInfo(mSelectDisplayInfo);
                        int status = DrmDisplaySetting.getCurrentDpyConnState(display);
                        mSelectDisplayInfo.setStatus(status);
                        String[] modes = mSelectDisplayInfo.getOrginModes();
                        Log.v(TAG, "display " + display + ", status=" + status + ", modes=" + modes);
                        if (DPY_STATUS_CONNECTED == status && null != modes && modes.length > 0) {
                            DrmDisplaySetting.setDisplayModeTemp(mSelectDisplayInfo, index);
//                            String mode = Arrays.asList(modes).get(index);
//                            DrmDisplaySetting.setMode(display, mode);
                            if (USED_OFFON_RESOLUTION) {
                                sendSwitchDeviceOffOnMsg(control, SWITCH_STATUS_OFF_ON);
                            } else {
                                Message message = new Message();
                                message.what = MSG_SHOW_CONFIRM_DIALOG;
                                message.obj = control;
                                mHandler.sendMessageDelayed(message, 300);
                            }
                        } else {
                            Message message = new Message();
                            message.what = MSG_UPDATE_STATUS_UI;
                            message.obj = ITEM_CONTROL.REFRESH_DISPLAY_STATUS_INFO;
                            mHandler.sendMessage(message);
                        }
                    }
                }
            }
        }.start();
    }

packages/apps/Settings/src/com/android/settings/display/DrmDisplaySetting.java
     public static void setDisplayModeTemp(DisplayInfo di, int index) {
        String mode = Arrays.asList(di.getOrginModes()).get(index);
        setMode(di.getDisplayNo(), mode);
        tmpSetMode = mode;
    }
    public static void setDisplayModeTemp(DisplayInfo di, int index) {
        String mode = Arrays.asList(di.getOrginModes()).get(index);
        setMode(di.getDisplayNo(), mode);
        tmpSetMode = mode;
    }

    public static void setMode(int display, String mode) {
        RkDisplayOutputManager manager = new RkDisplayOutputManager();
        int result = manager.updateDisplayInfos();
        int type = manager.getCurrentInterface(display);
        logd("setMode display=" + display + ", type=" + type + ", mode=" + mode);
        manager.setMode(display, type, mode);
    }
frameworks$ vim ./base/core/java/android/os/RkDisplayOutputManager.java
public void setMode(int display, int type, String mode) {
        String iface = typetoface(type);

        try {
            mService.setMode(display, iface, mode);
        }catch (Exception e) {
            Log.e(TAG, "Error set mode :" + e);
            return;
        }
    }
    
  public RkDisplayOutputManager() {
        IBinder b = ServiceManager.getService("drm_device_management");
        if(b == null) {
            Log.e(TAG, "Unable to connect to display device management service! - is it running yet?");
            return;
        }
        mService = IRkDisplayDeviceManagementService.Stub.asInterface(b);

        int mMainState = getCurrentDpyConnState(MAIN_DISPLAY);
        try {
            // Get main display interface
            String[] display_iface = mService.listInterfaces(MAIN_DISPLAY);
            if(DBG) Log.d(TAG, "main display iface num is " + display_iface.length);
            if(display_iface != null && display_iface.length > 0 &&  mMainState==DRM_MODE_CONNECTED) {
                m_main_iface = new int[display_iface.length];
                for(int i = 0; i < m_main_iface.length; i++) {
                if(DBG) Log.d(TAG, display_iface[i]);
                    m_main_iface[i] = ifacetotype(display_iface[i]);
                }
            }

./base/services/core/java/com/android/server/RkDisplayDeviceManagementService.java
    public void setMode(int display, String iface, String mode) {
        boolean isSameProperty = false;
        String lastMode;

        mdrmModes.setMode(display, iface, mode);
    }
    public RkDisplayDeviceManagementService(Context context) {
        mContext = context;
        mdrmModes = new RkDisplayModes();
        mdrmModes.init();
        IntentFilter hdmiFilter = new IntentFilter();
        hdmiFilter.addAction(ACTION_PLUGGED);
        mHdmiReceiver = new HdmiReceiver(mdrmModes);
        mContext.registerReceiver(mHdmiReceiver,hdmiFilter);
    }

./base/services/core/java/com/android/server/rkdisplay/RkDisplayModes.java
    public void setMode(int display, String iface, String mode){
        int ifaceType = ifacetotype(iface);
        String[] mode_str;
        int idx=0;
        RkDisplayModes.RkPhysicalDisplayInfo info;
        Log.w(TAG, "setMode " + mode + " display " + display);
        if (mode.contains("Auto")) {
            nativeSetMode(display, ifaceType, mode);//通过本地方法实现
        } else {
            mode_str = mode.split("-");
            for (String mval: mode_str){
            Log.e(TAG, "setMode split:  " + mval);
        }

        if (mode_str.length != 2){
            return;
        }

        idx = Integer.parseInt(mode_str[1]);
        if (mMainDisplayInfos!=null && idx >= mMainDisplayInfos.length && display==0)
            idx=0;
        else if (mAuxDisplayInfos!=null && idx >= mAuxDisplayInfos.length && display==1)
            idx=0;

        if (display == 0)
            info = mMainDisplayInfos[idx];
        else
            info = mAuxDisplayInfos[idx];

        StringBuilder builder = new StringBuilder();
        builder.append(info.width).append("x").append(info.height);
/*
        if (info.interlaceFlag == true)
            builder.append("i");
        else
            builder.append("p");
*/
        builder.append("@");
        builder.append(String.format(Locale.ENGLISH, "%.2f", info.refreshRate));
        builder.append("-");
        builder.append(info.hsync_start);
        builder.append("-");
        builder.append(info.hsync_end);
        builder.append("-");
        builder.append(info.htotal);
        builder.append("-");
        builder.append(info.vsync_start)
        .append("-").append(info.vsync_end).append("-").append(info.vtotal).append("-").append(String.format(Locale.ENGLISH, "%x", info.flags)).append("-").append(info.clock);

        nativeSetMode(display, ifaceType, builder.toString());
    }
    }
base/services/core/jni/com_android_server_rkdisplay_RkDisplayModes.cpp 
#include <rockchip/hardware/outputmanager/1.0/IRkOutputManager.h>  
static void nativeSetMode(JNIEnv* env, jobject obj, jint dpy, jint iface_type, jstring mode)
{
    const char* mMode = env->GetStringUTFChars(mode, NULL);

    if (mComposer != nullptr)
        mComposer->setMode(dpy, mMode); //这里又调用了hal层的方法
    env->ReleaseStringUTFChars(mode, mMode);
}
static void nativeInit(JNIEnv* env, jobject obj) {
        mComposer = IRkOutputManager::getService();//通过IRkOutputManager实现hdmi分辨率写入的
        if (mComposer != nullptr) {
            mComposer->initial();
        } else {
            ALOGD("nativeInit failed to get IRkOutputManager");
        }
}
./vendor/rockchip/hardware/interfaces/outputmanager/1.0/default/RkOutputManager.cpp
Return<Result> RkOutputManager::setMode(Display display, const hidl_string& mode)
{
    std::string modeStd(mode.c_str());

    mHwOutput->setMode(mHwOutput, display, modeStd.c_str());  //找到设备写入的地方
    return Result::OK;
}
IRkOutputManager* HIDL_FETCH_IRkOutputManager(const char* /* name */) {
    struct hw_output_device*   mHwOutput;
    const hw_module_t* hw_module = nullptr;
    int ret = hw_get_module(HW_OUTPUT_HARDWARE_MODULE_ID, &hw_module);//找到这个设备,获取设备,设备的具体实现在hw_output.cpp

    if (ret == 0) {
        ret = hw_output_open(hw_module, &mHwOutput);
        if (ret == 0) {
            return new RkOutputManager(mHwOutput);
        } else {
            LOG(ERROR) << "Passthrough failed to load legacy HAL.";
            return nullptr;
        }
    }
    else {
        LOG(ERROR) << "hw_get_module " << HWC_HARDWARE_MODULE_ID
                   << " failed: " << ret;
        return nullptr;
    }
}
hardware/libhardware/modules/hw_output/hw_output.cpp
static int hw_output_device_open(const struct hw_module_t* module,
        const char* name, struct hw_device_t** device)
{
    int status = -EINVAL;
    if (!strcmp(name, HW_OUTPUT_DEFAULT_DEVICE)) {
        hw_output_private_t* dev = (hw_output_private_t*)malloc(sizeof(*dev));

        /* initialize our state here */
        //memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version = HW_OUTPUT_DEVICE_API_VERSION_0_1;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        dev->device.common.close = hw_output_device_close;

        dev->device.initialize = hw_output_initialize;
        dev->device.setMode = hw_output_set_mode; //这里传递一个函数指针,具体设置分辨率的地方
..........
static int hw_output_set_mode(struct hw_output_device* dev, int dpy, const char* mode)
{
    hw_output_private_t* priv = (hw_output_private_t*)dev;
    DrmConnector* conn = getValidDrmConnector(priv, dpy);
    BaseParameter* mBaseParameter = priv->mBaseParmeter;
    char property[PROPERTY_VALUE_MAX];
    std::string propertyStr;

    propertyStr = getPropertySuffix(priv, "persist.vendor.resolution.", dpy);

    ALOGD("nativeSetMode %s display %d", mode, dpy);

    if (strcmp(mode, property) !=0) {
        property_set(propertyStr.c_str(), mode);
        updateTimeline();
        struct disp_info info;
        float vfresh=0.0f;
        int slot = 0;

        mBaseParameter->get_disp_info(conn->get_type(), conn->connector_id(), &info);
        slot = findSuitableInfoSlot(&info, conn->get_type(), conn->connector_id());
        info.screen_info[slot].type = conn->get_type();
        info.screen_info[slot].id = conn->connector_id();
        if (strncmp(mode, "Auto", 4) != 0 && strncmp(mode, "0x0p0-0", 7) !=0) {
            sscanf(mode,"%dx%d@%f-%d-%d-%d-%d-%d-%d-%x-%d",
                    &info.screen_info[slot].resolution.hdisplay, &info.screen_info[slot].resolution.vdisplay,
                    &vfresh, &info.screen_info[slot].resolution.hsync_start,&info.screen_info[slot].resolution.hsync_end,
                    &info.screen_info[slot].resolution.htotal,&info.screen_info[slot].resolution.vsync_start,
                    &info.screen_info[slot].resolution.vsync_end, &info.screen_info[slot].resolution.vtotal,
                    &info.screen_info[slot].resolution.flags, &info.screen_info[slot].resolution.clock);
           info.screen_info[slot].resolution.vrefresh = (int)vfresh;
        } else {
            info.screen_info[slot].feature|= RESOLUTION_AUTO;
            memset(&info.screen_info[slot].resolution, 0, sizeof(info.screen_info[slot].resolution));
        }
        mBaseParameter->set_disp_info(conn->get_type(), conn->connector_id(), &info);
    }
    return 0;
}





  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Android 5.1是一个广泛使用的操作系统版本,支持HDMI输出功能。要设置HDMI分辨率,可以按照以下步骤进行: 1. 首先,将Android设备与HDMI显示器或电视连接。确保HDMI线缆正常连接。 2. 在Android设备上打开设置菜单。可以通过下拉通知栏或点击主屏幕上的设置图标来访问设置菜单。 3. 在设置菜单中,向下滚动并找到“显示”选项。点击进入显示设置页面。 4. 在显示设置页面中,可能会看到“屏幕投射”或“显示模式”的选项。点击进入相关设置。 5. 在屏幕投射或显示模式设置页面中,可以看到HDMI选项。点击进入HDMI设置。 6. 在HDMI设置页面中,通常会有分辨率选项。点击进入分辨率设置。 7. 在分辨率设置页面中,可以看到可用的分辨率选项列表。根据显示器或电视的支持能力和个人偏好,选择所需的分辨率。 8. 选择完分辨率后,点击确认或应用。系统将应用所选的分辨率设置。 9. 返回到上一个菜单或主屏幕,查看是否已成功设置HDMI分辨率。显示器或电视上的画面应该会根据所选的分辨率进行调整。 需要注意的是,不同的Android设备或系统版本可能会有略微不同的设置流程。因此,根据具体的设备和系统版本,上述步骤可能会有所变化。但总体而言,通过进入设置菜单,找到显示设置,再进入HDMI设置,选择适当的分辨率,就可以完成Android 5.1设置HDMI分辨率流程。 ### 回答2: Android 5.1版本的设备在设置HDMI分辨率时,可以按照以下步骤进行操作: 1. 连接HDMI线缆:首先,将一端的HDMI线缆插入Android设备的HDMI输出接口,另一端插入显示设备(如电视或投影仪)的HDMI输入接口。 2. 打开设置界面:在Android设备上,找到并点击打开“设置”应用程序,通常可以在应用程序列表中找到该选项。 3. 进入显示设置:在“设置”主界面中,向下滚动并找到“显示”选项,点击进入显示设置界面。 4. 选择HDMI设置:在显示设置界面中,找到并点击“HDMI”选项,这将打开HDMI设置界面。 5. 选择分辨率:在HDMI设置界面中,通常会显示可用的HDMI分辨率选项。根据你的显示设备和个人需求,选择适当的分辨率选项。 6. 保存设置:选择完分辨率后,点击界面上的“保存”或“应用”按钮,以保存并应用新的HDMI分辨率设置。 7. 测试分辨率:你可以通过在显示设备上观察图像是否清晰和完整来测试新的HDMI分辨率设置。如果满意,设置流程就结束了。 请注意,以上步骤仅适用于Android 5.1版本的系统设备,不同的Android版本或设备类型可能略有不同。确保你的设备支持HDMI输出功能并运行在Android 5.1版本或更高版本。 ### 回答3: 要设置Android 5.1的HDMI分辨率,可以按照以下流程操作: 1. 首先,确保你的Android设备已连接到HDMI显示器上。 2. 在设备上滑动屏幕,进入主菜单,找到并点击“设置”图标。 3. 在设置菜单中,向下滚动找到“显示”或类似的选项,并点击进入。 4. 在显示设置菜单中,找到“屏幕分辨率”或类似的选项,并点击进入。 5. 系统会列出可用的屏幕分辨率选项。根据你的需求和HDMI显示器的能力,选择一个适合的分辨率。 6. 点击选中分辨率后,系统会提示你是否确认应用此分辨率。确认后,系统会应用新的分辨率设置。 7. 返回到主菜单或桌面,你会注意到HDMI显示器的分辨率已经改变为你所设置分辨率。 需要注意的是,不同的Android设备可能会在设置菜单的布局和选项名称上有所区别,具体操作可能会有所不同。但一般来说,通过“设置”-“显示”-“屏幕分辨率”可以找到相关的选项。 如果你在Android设备上找不到上述选项,可能是因为该设备的固件版本或制造商定制的界面导致了菜单布局的差异。在这种情况下,你可能需要查阅设备的用户手册或进行在线搜索来了解具体的设置方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术求索者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值