Android最近任务显示的图片

Android最近任务显示的图片

  • 1、TaskSnapshot截图
    • 1.1 snapshotTask
    • 1.2 drawAppThemeSnapshot
  • 2、导航栏显示问题
  • 3、Recentan按键进入最近任务

1、TaskSnapshot截图

frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
frameworks/base/core/java/android/view/SurfaceControl.java
frameworks/base/core/jni/android_view_SurfaceControl.cpp
frameworks/native/libs/gui/SurfaceComposerClient.cpp
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

截图保存路径:data/system_ce/0/snapshots

TaskSnapshot captureTaskSnapshot(Task task, boolean snapshotHome) {final TaskSnapshot snapshot;if (snapshotHome) {snapshot = snapshotTask(task);} else {switch (getSnapshotMode(task)) {case SNAPSHOT_MODE_NONE:return null;case SNAPSHOT_MODE_APP_THEME:snapshot = drawAppThemeSnapshot(task);break;case SNAPSHOT_MODE_REAL:snapshot = snapshotTask(task);break;default:snapshot = null;break;}}return snapshot;
}

1.1 snapshotTask

SNAPSHOT_MODE_REAL:截图一张真实的屏幕截图作为快照。
实际截图缓存 SurfaceControl.captureLayersExcluding -> ScreenshotClient::captureLayers -> SurfaceFlinger::captureLayers

TaskSnapshot snapshotTask(Task task, int pixelFormat) {TaskSnapshot.Builder builder = new TaskSnapshot.Builder();if (!prepareTaskSnapshot(task, pixelFormat, builder)) {// Failed some pre-req. Has been logged.return null;}final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =createTaskSnapshot(task, builder);if (screenshotBuffer == null) {// Failed to acquire image. Has been logged.return null;}builder.setSnapshot(screenshotBuffer.getHardwareBuffer());builder.setColorSpace(screenshotBuffer.getColorSpace());return builder.build();
}SurfaceControl.ScreenshotHardwareBuffer createTaskSnapshot(@NonNull Task task,TaskSnapshot.Builder builder) {Point taskSize = new Point();final SurfaceControl.ScreenshotHardwareBuffer taskSnapshot = createTaskSnapshot(task,mHighResTaskSnapshotScale, builder.getPixelFormat(), taskSize, builder);builder.setTaskSize(taskSize);return taskSnapshot;
}SurfaceControl.ScreenshotHardwareBuffer createTaskSnapshot(@NonNull Task task,float scaleFraction, int pixelFormat, Point outTaskSize, TaskSnapshot.Builder builder) {if (task.getSurfaceControl() == null) {if (DEBUG_SCREENSHOT) {Slog.w(TAG_WM, "Failed to take screenshot. No surface control for " + task);}return null;}task.getBounds(mTmpRect);mTmpRect.offsetTo(0, 0);SurfaceControl[] excludeLayers;final WindowState imeWindow = task.getDisplayContent().mInputMethodWindow;// Exclude IME window snapshot when IME isn't proper to attach to app.final boolean excludeIme = imeWindow != null && imeWindow.getSurfaceControl() != null&& !task.getDisplayContent().shouldImeAttachedToApp();final WindowState navWindow =task.getDisplayContent().getDisplayPolicy().getNavigationBar();// If config_attachNavBarToAppDuringTransition is true, the nav bar will be reparent to the// the swiped app when entering recent app, therefore the task will contain the navigation// bar and we should exclude it from snapshot.final boolean excludeNavBar = navWindow != null;if (excludeIme && excludeNavBar) {excludeLayers = new SurfaceControl[2];excludeLayers[0] = imeWindow.getSurfaceControl();excludeLayers[1] = navWindow.getSurfaceControl();} else if (excludeIme || excludeNavBar) {excludeLayers = new SurfaceControl[1];excludeLayers[0] =excludeIme ? imeWindow.getSurfaceControl() : navWindow.getSurfaceControl();} else {excludeLayers = new SurfaceControl[0];}builder.setHasImeSurface(!excludeIme && imeWindow != null && imeWindow.isVisible());final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =SurfaceControl.captureLayersExcluding(task.getSurfaceControl(), mTmpRect, scaleFraction,pixelFormat, excludeLayers);if (outTaskSize != null) {outTaskSize.x = mTmpRect.width();outTaskSize.y = mTmpRect.height();}final HardwareBuffer buffer = screenshotBuffer == null ? null: screenshotBuffer.getHardwareBuffer();if (isInvalidHardwareBuffer(buffer)) {return null;}return screenshotBuffer;
}

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,const sp<IScreenCaptureListener>& captureListener) {ATRACE_CALL();status_t validate = validateScreenshotPermissions(args);if (validate != OK) {return validate;}ui::Size reqSize;sp<Layer> parent;Rect crop(args.sourceCrop);std::unordered_set<sp<Layer>, SpHash<Layer>> excludeLayers;ui::Dataspace dataspace;// Call this before holding mStateLock to avoid any deadlocking.bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission();{Mutex::Autolock lock(mStateLock);parent = fromHandle(args.layerHandle).promote();if (parent == nullptr) {ALOGE("captureLayers called with an invalid or removed parent");return NAME_NOT_FOUND;}if (!canCaptureBlackoutContent &&parent->getDrawingState().flags & layer_state_t::eLayerSecure) {ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");return PERMISSION_DENIED;}Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState());if (args.sourceCrop.width() <= 0) {crop.left = 0;crop.right = parentSourceBounds.getWidth();}if (args.sourceCrop.height() <= 0) {crop.top = 0;crop.bottom = parentSourceBounds.getHeight();}if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) {// Error out if the layer has no source bounds (i.e. they are boundless) and a source// crop was not specified, or an invalid frame scale was provided.return BAD_VALUE;}reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY);for (const auto& handle : args.excludeHandles) {sp<Layer> excludeLayer = fromHandle(handle).promote();if (excludeLayer != nullptr) {excludeLayers.emplace(excludeLayer);} else {ALOGW("Invalid layer handle passed as excludeLayer to captureLayers");return NAME_NOT_FOUND;}}// The dataspace is depended on the color mode of display, that could use non-native mode// (ex. displayP3) to enhance the content, but some cases are checking native RGB in bytes,// and failed if display is not in native mode. This provide a way to force using native// colors when capture.dataspace = args.dataspace;} // mStateLock// really small crop or frameScaleif (reqSize.width <= 0 || reqSize.height <= 0) {ALOGW("Failed to captureLayes: crop or scale too small");return BAD_VALUE;}Rect layerStackSpaceRect(0, 0, reqSize.width, reqSize.height);bool childrenOnly = args.childrenOnly;RenderAreaFuture renderAreaFuture = ftl::defer([=]() -> std::unique_ptr<RenderArea> {return std::make_unique<LayerRenderArea>(*this, parent, crop, reqSize, dataspace,childrenOnly, layerStackSpaceRect,args.captureSecureLayers);});auto traverseLayers = [parent, args, excludeLayers](const LayerVector::Visitor& visitor) {parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {if (!layer->isVisible()) {return;} else if (args.childrenOnly && layer == parent.get()) {return;} else if (args.uid != CaptureArgs::UNSET_UID && args.uid != layer->getOwnerUid()) {return;}sp<Layer> p = layer;while (p != nullptr) {if (excludeLayers.count(p) != 0) {return;}p = p->getParent();}visitor(layer);});};if (captureListener == nullptr) {ALOGE("capture screen must provide a capture listener callback");return BAD_VALUE;}auto future = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,args.pixelFormat, args.allowProtected, args.grayscale,captureListener);return fenceStatus(future.get());
}

1.2 drawAppThemeSnapshot

SNAPSHOT_MODE_APP_THEME:不允许截图真实的屏幕截图,但我们应该尝试使用应用程序主题来创建应用程序的虚假表示。

/*** If we are not allowed to take a real screenshot, this attempts to represent the app as best* as possible by using the theme's window background.*/
private TaskSnapshot drawAppThemeSnapshot(Task task) {final ActivityRecord topChild = task.getTopMostActivity();if (topChild == null) {return null;}final WindowState mainWindow = topChild.findMainWindow();if (mainWindow == null) {return null;}final int color = ColorUtils.setAlphaComponent(task.getTaskDescription().getBackgroundColor(), 255);final LayoutParams attrs = mainWindow.getAttrs();final Rect taskBounds = task.getBounds();final InsetsState insetsState = mainWindow.getInsetsStateWithVisibilityOverride();final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrame(), insetsState);final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,attrs.privateFlags, attrs.insetsFlags.appearance, task.getTaskDescription(),mHighResTaskSnapshotScale, insetsState);final int taskWidth = taskBounds.width();final int taskHeight = taskBounds.height();final int width = (int) (taskWidth * mHighResTaskSnapshotScale);final int height = (int) (taskHeight * mHighResTaskSnapshotScale);final RenderNode node = RenderNode.create("TaskSnapshotController", null);node.setLeftTopRightBottom(0, 0, width, height);node.setClipToBounds(false);final RecordingCanvas c = node.start(width, height);c.drawColor(color);decorPainter.setInsets(systemBarInsets);decorPainter.drawDecors(c /* statusBarExcludeFrame */);node.end(c);final Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, width, height);if (hwBitmap == null) {return null;}final Rect contentInsets = new Rect(systemBarInsets);final Rect letterboxInsets = topChild.getLetterboxInsets();InsetUtils.addInsets(contentInsets, letterboxInsets);// Note, the app theme snapshot is never translucent because we enforce a non-translucent// color abovereturn new TaskSnapshot(System.currentTimeMillis() /* id */,topChild.mActivityComponent, hwBitmap.getHardwareBuffer(),hwBitmap.getColorSpace(), mainWindow.getConfiguration().orientation,mainWindow.getWindowConfiguration().getRotation(), new Point(taskWidth, taskHeight),contentInsets, letterboxInsets, false /* isLowResolution */,false /* isRealSnapshot */, task.getWindowingMode(),getAppearance(task), false /* isTranslucent */, false /* hasImeSurface */);
}

2、导航栏显示问题

应用设置导航栏可避免图片底部黑条

<item name="android:enforceNavigationBarContrast">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>

3、Recentan按键进入最近任务

<!-- Component name for the activity that will be presenting the Recents UI, which will receivespecial permissions for API related to fetching and presenting recent tasks. The defaultconfiguration uses Launcehr3QuickStep as default launcher and points to the correspondingrecents component. When using a different default launcher, change this appropriately oruse the default systemui implementation: com.android.systemui/.recents.RecentsActivity -->
<string name="config_recentsComponentName" translatable="false">com.android.launcher3/com.android.quickstep.RecentsActivity</string>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/41112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决C++编译时的产生的skipping incompatible xxx 错误

问题 我在编译项目时&#xff0c;产生了一个 /usr/bin/ld: skipping incompatible ../../xxx/ when searching for -lxxx 的编译错误&#xff0c;如下图所示&#xff1a; 解决方法 由图中的错误可知&#xff0c;在编译时&#xff0c;是能够在我们指定目录下的 *.so 动态库的…

python函数和c的区别有哪些

Python有很多内置函数&#xff08;build in function&#xff09;&#xff0c;不需要写头文件&#xff0c;Python还有很多强大的模块&#xff0c;需要时导入便可。C语言在这一点上远不及Python&#xff0c;大多时候都需要自己手动实现。 C语言中的函数&#xff0c;有着严格的顺…

Java基础(六)——继承

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

【Web】

1、配仓库 [rootlocalhost yum.repos.d]# vi rpm.repo ##本地仓库标准写法 [baseos] namemiaoshubaseos baseurl/mnt/BaseOS gpgcheck0 [appstream] namemiaoshuappstream baseurlfile:///mnt/AppStream gpgcheck0 2、挂载 [rootlocalhost ~]mount /dev/sr0 /mnt mount: /m…

Vulnhub-Os-hackNos-1(包含靶机获取不了IP地址)

https://download.vulnhub.com/hacknos/Os-hackNos-1.ova #靶机下载地址 题目&#xff1a;要找到两个flag user.txt root.txt 文件打开 改为NAT vuln-hub-OS-HACKNOS-1靶机检测不到IP地址 重启靶机 按住shift 按下键盘字母"E"键 将图中ro修改成…

Vue 3集成krpano 全景图展示

Vue 3集成krpano 全景图展示 星光云全景系统源码 VR全景体验地址 星光云全景VR系统 将全景krpano静态资源文件vtour放入vue项目中 导入vue之前需要自己制作一个全景图 需要借助官方工具进行制作 工具下载地址&#xff1a;krpano工具下载地址 注意事项&#xff1a;vuecli…

Hook 实现 Windows 系统热键屏蔽(二)

目录 前言 一、介绍用户账户控制&#xff08;UAC&#xff09; 1.1 什么是 UAC &#xff1f; 2.2 UAC 运行机制的概述 2.3 分析 UAC 提权参数 二、 NdrAsyncServerCall 函数的分析 2.1 函数声明的解析 2.2 对 Winlogon 的逆向 2.3 对 rpcrt4 的静态分析 2.4 对 rpcrt4…

YOLOv8_obb数据集可视化[旋转目标检测实践篇]

先贴代码,周末再补充解析。 这个篇章主要是对标注好的标签进行可视化,虽然比较简单,但是可以从可视化代码中学习到YOLOv8是如何对标签进行解析的。 import cv2 import numpy as np import os import randomdef read_obb_labels(label_file_path):with open(label_file_path,…

清新简约之美,开源个人博客:Jekyll Theme Chirpy

Jekyll Theme Chirpy&#xff1a;简约不简单&#xff0c;Chirpy 让你的博客焕发新意- 精选真开源&#xff0c;释放新价值。 概览 Jekyll Theme Chirpy 是为Jekyll静态网站生成器设计的现代主题&#xff0c;以其清新、简约的设计风格和用户友好的交互体验受到开发者和博客作者的…

为企业知识库选模型?全球AI大模型知识库RAG场景基准测试排名

大语言模型常见基准测试 大家对于AI模型理解和推理能力的的基准测试一定非常熟悉了&#xff0c;比如MMLU&#xff08;大规模多任务语言理解&#xff09;、GPQA&#xff08;研究生级别知识问答&#xff09;、GSMSK&#xff08;研究生数学知识考察&#xff09;、MATH&#xff08…

Zabbix监控软件

目录 一、什么是Zabbix 二、zabbix监控原理 三、zabbix 安装步骤 一、什么是Zabbix ●zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 ●zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的…

【多线程】进程与线程

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1. 操作系统1.1 什么是操作系统1.2 操作系统主要的功能 2. 进程2.1 什么是进程2.2 通过PCB描述一…

代码随想录算法训练营第22天|LeetCode 77. 组合、216.组合总和III、17.电话号码的字母组合

1. LeetCode 77. 组合 题目链接&#xff1a;https://leetcode.cn/problems/combinations/description/ 文章链接&#xff1a;https://programmercarl.com/0077.组合.html 视频链接&#xff1a;https://www.bilibili.com/video/BV1ti4y1L7cv 思路&#xff1a;利用递归回溯的方式…

nanodiffusion代码逐行理解之diffusion

目录 一、diffusion创建二、GaussianDiffusion定义三、代码理解def __init__(self,model,img_size,img_channels,num_classes,betas, loss_type"l2", ema_decay0.9999, ema_start5000, ema_update_rate1,):def remove_noise(self, x, t, y, use_emaTrue):def sample(…

MySQL 集群

MySQL 集群有多种类型&#xff0c;每种类型都有其特定的用途和优势。以下是一些常见的 MySQL 集群解决方案&#xff1a; 1. MySQL Replication 描述&#xff1a;MySQL 复制是一种异步复制机制&#xff0c;允许将一个 MySQL 数据库的数据复制到一个或多个从服务器。 用途&…

一拖二快充线:生活充电新风尚,高效便捷解决双设备充电难题

一拖二快充线在生活应用领域的优势与双接充电的便携性问题 在现代快节奏的生活中&#xff0c;电子设备已成为我们不可或缺的日常伴侣。无论是智能手机、平板电脑还是笔记本电脑&#xff0c;它们在我们的工作、学习和娱乐中扮演着至关重要的角色。然而&#xff0c;随着设备数量…

产品经理系列1—如何实现一个电商系统

具体笔记如下&#xff0c;主要按获客—找货—下单—售后四个部分进行模块拆解

代码随想录算法训练Day58|LeetCode417-太平洋大西洋水流问题、LeetCode827-最大人工岛

太平洋大西洋水流问题 力扣417-太平洋大西洋水流问题 有一个 m n 的矩形岛屿&#xff0c;与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界&#xff0c;而 “大西洋” 处于大陆的右边界和下边界。 这个岛被分割成一个由若干方形单元格组成的网格。给定一个…

【Unity】unity学习扫盲知识点

1、建议检查下SystemInfo的引用。这个是什么 Unity的SystemInfo类提供了一种获取关于当前硬件和操作系统的信息的方法。这包括设备类型&#xff0c;操作系统&#xff0c;处理器&#xff0c;内存&#xff0c;显卡&#xff0c;支持的Unity特性等。使用SystemInfo类非常简单。它的…

Linux 查看磁盘是不是 ssd 的方法

lsblk 命令检查 $ lsblk -d -o name,rota如果 ROTA 值为 1&#xff0c;则磁盘类型为 HDD&#xff0c;如果 ROTA 值为 0&#xff0c;则磁盘类型为 SSD。可以在上面的屏幕截图中看到 sda 的 ROTA 值是 1&#xff0c;表示它是 HDD。 2. 检查磁盘是否旋转 $ cat /sys/block/sda/q…