热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

AndroidTV切换系统输出分辨率的一些思考

Android12后的一些思考:是否可以使用原生的某些接口实现切换系统分辨率呢? 参考文章:https:blog.csdn.netu014535072articledetails1

Android 12 后的一些思考:是否可以使用原生的某些接口实现切换系统分辨率呢?

 

参考文章:

https://blog.csdn.net/u014535072/article/details/108692559

 

从源码中看到的可能相关的内容:

 /frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java

中的方法:

@Override
public void setDisplayProperties(int displayId, boolean hasContent,
float requestedRefreshRate, int requestedMode, float requestedMinRefreshRate,
float requestedMaxRefreshRate, boolean requestedMinimalPostProcessing,
boolean inTraversal) {
setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
requestedMode, requestedMinRefreshRate, requestedMaxRefreshRate,
requestedMinimalPostProcessing, inTraversal);
}

 

获取支持的Display mode:

 

获取Display info的参看

/packages/apps/Launcher3/src/com/android/launcher3/util/DisplayController.java

private final DisplayManager mDM;
mDM = context.getSystemService(DisplayManager.class);
Display display = mDM.getDisplay(DEFAULT_DISPLAY);

基础的Display类

/frameworks/base/core/java/android/view/Display.java

/**
* Returns the active mode of the display.
*/
public Mode getMode() {
synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.getMode();
}
}
/**
* Gets the supported modes of this display.
*/
public Mode[] getSupportedModes() {
synchronized (mLock) {
updateDisplayInfoLocked();
final Display.Mode[] modes = mDisplayInfo.supportedModes;
return Arrays.copyOf(modes, modes.length);
}
}

 

Display::Mode的定义:

http://aospxref.com/android-12.0.0_r3/xref/frameworks/base/core/java/android/view/Display.java#1696

 

一个例子demo

http://aospxref.com/android-12.0.0_r3/xref/cts/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/ModeSwitchingTestActivity.java#66

DisplayManager displayManager = getSystemService(DisplayManager.class);
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
List modeList = findTestModes(display);
Display.Mode lastMode = display.getMode();

private List findTestModes(Display display) {
Display.Mode activeMode = display.getMode();
List modeList = new ArrayList<>();
// Find a mode to test refresh rate switch - the mode with smallest refresh rate and
// the same resolution as the active mode
Arrays.stream(display.getSupportedModes())
.filter(mode -> !mode.equals(activeMode))
.filter(mode -> isResolutionEqual(mode, activeMode))
.min(Comparator.comparingDouble(Display.Mode::getRefreshRate))
.ifPresent(modeList::add);
// Find a mode to test seamless mode switch.
if (modeList.size() > 0 && !DisplayUtil.isModeSwitchSeamless(activeMode, modeList.get(0))
&& activeMode.getAlternativeRefreshRates().length > 0) {
Arrays.stream(display.getSupportedModes())
.filter(mode -> !mode.equals(activeMode))
.filter(mode -> DisplayUtil.isModeSwitchSeamless(activeMode, mode))
.findFirst()
.ifPresent(modeList::add);
}
// Find a mode to test resolution switch - the first 16:9 mode with resolution less
// than the active mode.
Arrays.stream(display.getSupportedModes())
.filter(mode -> !mode.equals(activeMode))
.filter(mode -> !isResolutionEqual(mode, activeMode))
.filter(this::is16to9)
.max(Comparator.comparing(Display.Mode::getPhysicalHeight))
.ifPresent(modeList::add);
return modeList;
}

 

我目前遇到的问题是不是可以直接在apk中加上这一个来通知到 WM 、SurfaceFLinger呢?

private Display.Mode mNextMode;
@Override
public void runTest() {
Window window = mContext.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.preferredDisplayModeId = mNextMode.getModeId();
window.setAttributes(params);
}

 

 

 

另一个可能的途径:

 /frameworks/base/core/java/android/view/SurfaceControl.java

/**
* @hide
*/
public static boolean setDesiredDisplayModeSpecs(IBinder displayToken,
DesiredDisplayModeSpecs desiredDisplayModeSpecs) {
if (displayToken == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
if (desiredDisplayModeSpecs == null) {
throw new IllegalArgumentException("desiredDisplayModeSpecs must not be null");
}
if (desiredDisplayModeSpecs.defaultMode <0) {
throw new IllegalArgumentException("defaultMode must be non-negative");
}
return nativeSetDesiredDisplayModeSpecs(displayToken, desiredDisplayModeSpecs);
}

// Verify that this will reapply the desired modes.
verify(mSurfaceControlProxy).setDesiredDisplayModeSpecs(display.token,
new SurfaceControl.DesiredDisplayModeSpecs(
/* baseModeId */ 2,
/* allowGroupSwitching */ false,
/* primaryRange */ 60f, 60f,
/* appRange */ 60f, 60f
));

 

 

 

 

SurfaceFlinger

void SurfaceFlinger::loadDisplayModes(PhysicalDisplayId displayId, DisplayModes& outModes,
DisplayModePtr& outActiveMode) const {

activeModeHwcId = getHwComposer().getActiveMode(displayId);
}

只有这里去HWC 获取 getActiveMode

 

 

 

 

 

/frameworks/base/core/java/android/view/SurfaceControl.java

通知到SurfaceFlinger???

setDisplaySize
--> DisplayState::eDisplaySizeChanged
--> eDisplayTransactionNeeded
--> processDisplayHotplugEventsLocked
--> loadDisplayModes
--> getHwComposer().getActiveMode(displayId);

 

 

获取displayToken

private Bitmap captureScreenshot(Rect crop) {
int width = crop.width();
int height = crop.height();
Bitmap screenshot = null;
final Display display = getDefaultDisplay();
final DisplayAddress address = display.getAddress();
if (!(address instanceof DisplayAddress.Physical)) {
Log.e(TAG, "Skipping Screenshot - Default display does not have a physical address: "
+ display);
} else {
final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) address;
final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(
physicalAddress.getPhysicalDisplayId());
final SurfaceControl.DisplayCaptureArgs captureArgs =
new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
.setSourceCrop(crop)
.setSize(width, height)
.build();
final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
SurfaceControl.captureDisplay(captureArgs);
screenshot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
}
return screenshot;
}

 

心有猛虎,细嗅蔷薇,生活就该无惧无悔



 

作者:二的次方 出处:https://www.cnblogs.com/roger-yu/p/15997843.html 本文版权归作者和博客园共有,转载必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利



推荐阅读
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • Navicat Premium 15 安装指南及数据库连接配置
    本文详细介绍 Navicat Premium 15 的安装步骤及其对多种数据库(如 MySQL 和 Oracle)的支持,帮助用户顺利完成软件的安装与激活。 ... [详细]
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • Java 中 Writer flush()方法,示例 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文探讨了如何像程序员一样思考,强调了将复杂问题分解为更小模块的重要性,并讨论了如何通过妥善管理和复用已有代码来提高编程效率。 ... [详细]
  • python的交互模式怎么输出名文汉字[python常见问题]
    在命令行模式下敲命令python,就看到类似如下的一堆文本输出,然后就进入到Python交互模式,它的提示符是>>>,此时我们可以使用print() ... [详细]
  • 火星商店问题:线段树分治与持久化Trie树的应用
    本题涉及编号为1至n的火星商店,每个商店有一个永久商品价值v。操作包括每天在指定商店增加一个新商品,以及查询某段时间内某些商店中所有商品(含永久商品)与给定密码值的最大异或结果。通过线段树分治和持久化Trie树来高效解决此问题。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 本文总结了汇编语言中第五至第八章的关键知识点,涵盖间接寻址、指令格式、安全编程空间、逻辑运算指令及数据重复定义等内容。通过详细解析这些内容,帮助读者更好地理解和应用汇编语言的高级特性。 ... [详细]
  • 探讨如何高效使用FastJSON进行JSON数据解析,特别是从复杂嵌套结构中提取特定字段值的方法。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细介绍了如何使用Maven高效管理多模块项目,涵盖项目结构设计、依赖管理和构建优化等方面。通过具体的实例和配置说明,帮助开发者更好地理解和应用Maven在复杂项目中的优势。 ... [详细]
  • 本文介绍了如何在具备多个IP地址的FTP服务器环境中,通过动态地址端口复用和地址转换技术优化网络配置。重点讨论了2Mb/s DDN专线连接、Cisco 2611路由器及内部网络地址规划。 ... [详细]
author-avatar
博客百度2
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有