AOSP开机动画调测技术点(基于Android13)

AOSP开机动画调测技术点(基于Android13)

开机动画替换

  1. 首先,在你的计算机上创建一个名为"bootanimation"的文件夹,并将"part0"、"part1"和"desc.txt"这三个文件复制到该文件夹中。这些文件包含了开机动画的图像帧和描述信息。

  2. 在命令行中切换到bootanimation文件夹,并执行以下命令将文件夹中的内容打包成一个名为"bootanimation.zip"的压缩文件:

zip -r -0 bootanimation.zip part0 part1 desc.txt

这个命令的含义是将当前目录下的"part0"、"part1"和"desc.txt"三个文件打包成一个名为"bootanimation.zip"的压缩文件。

  • -r:表示递归地将指定目录下的所有文件和子目录都包含在压缩文件中。
  • -0:表示使用不进行压缩的存储模式,即不对文件进行压缩处理,直接存储到压缩包中。
  1. 使用ADB(Android Debug Bridge)将生成的bootanimation.zip文件复制到设备的/system/media/目录中。请注意,这一步需要设备具有root权限以及重新挂载/system分区。你可以使用以下命令完成这一步骤:
adb root
adb remount
adb push bootanimation.zip /system/media/
  1. 执行以下命令来启动新的开机动画:
   adb shell setprop service.bootanim.exit 0adb shell setprop ctl.start bootanim
  1. 现在你可以观察到新的开机动画效果。如果想退出新的开机动画,执行以下命令:
   adb shell setprop service.bootanim.exit 1

Android开机动画(desc.txt)格式

开机动画分为2个阶段的图片资源加载,part0和part2, 加载规则在desc.txt文件中进行描述

desc.txt  part0  part1

part0与part1中的图片需要按照数字大小顺序标记。

desc.txt内容如下:

通用参数

第一行定义了动画的一般参数:

WIDTH HEIGHT FPS [PROGRESS]
  • WIDTH: 动画的宽度(像素)
  • HEIGHT: 动画的高度(像素)
  • FPS: 每秒的帧数,例如60
  • PROGRESS: 是否在最后一部分显示进度百分比
    • 百分比将以"x"坐标为基准,在动画高度的1/3处显示。

动态着色属性

如果使用动态着色功能,则提供一个可选的行来指定动态着色属性的格式。如果不使用动态着色,则可以跳过此行。

动画部分

接下来,根据以下格式提供多行来定义动画的各个部分:

TYPE COUNT PAUSE PATH [FADE [#RGBHEX [CLOCK1 [CLOCK2]]]]
  • TYPE: 单个字符,表示此动画段的类型:
    • p – 该部分会播放,除非在启动结束之前被中断
    • c – 该部分将播放到完成,无论如何
    • f – 与 p 类似,但在继续播放的同时,指定的帧数正在淡出。只有第一个被中断的 f 部分会被淡出,其他后续的 f 部分会被跳过。
  • COUNT: 播放动画的次数,或者为0以无限循环,直到启动完成
  • PAUSE: 此部分结束后延迟的帧数
  • PATH: 包含此部分帧图片的目录(例如 part0
  • FADE: (仅适用于 f 类型) 被中断时要淡出的帧数,其中 0 表示立即淡出,使 f ... 0 的行为类似于 p,并且不将其视为淡出部分
  • RGBHEX: (可选) 背景颜色,表示为 #RRGGBB
  • CLOCK1, CLOCK2: (可选) 绘制当前时间(用于手表)的坐标:
    • 如果只提供 CLOCK1,则它是时钟的y坐标,x坐标默认为 c
    • 如果同时提供 CLOCK1CLOCK2,则 CLOCK1 是x坐标,CLOCK2 是y坐标
    • 值可以是正整数、负整数或 c
      • c – 将文本居中
      • n – 将文本定位到距起始位置的n像素处;在x轴上为左边缘,在y轴上为底部边缘
      • -n – 将文本定位到距结束位置的n像素处;在x轴上为右边缘,在y轴上为顶部边缘
    • 示例:
      • -24c -24 将文本定位到距离屏幕顶部24像素处,水平居中
      • 16 c 将文本定位到距离屏幕左侧16像素处,垂直居中
      • -32 32 将文本定位到距离屏幕边缘向上32像素,向左32像素的位置

此外,还有一个特殊的类型 $SYSTEM,它加载并播放 /system/media/bootanimation.zip
以上是关于Android开机动画的desc.txt配置文件的格式说明。该文件定义了动画的属性和各个部分的行为。

源码分析

frameworks/base/cmds/bootanimation

.
├── Android.bp
├── audioplay.cpp
├── audioplay.h
├── BootAnimation.cpp
├── BootAnimation.h
├── bootanimation_main.cpp
├── BootAnimationUtil.cpp
├── BootAnimationUtil.h
├── bootanim.rc
├── FORMAT.md
└── OWNERS

定义服务

开启动画启动规则定义在bootanim.rc

service bootanim /system/bin/bootanimationclass core animationuser graphicsgroup graphics audiodisabledoneshotioprio rt 0task_profiles MaxPerformance

开机动画的服务配置文件字段解释如下:

  • service: 指明服务的名称为"bootanim",即开机动画服务。
  • /system/bin/bootanimation: 指定了开机动画的执行文件路径为"/system/bin/bootanimation"。
  • class core animation: 表示此服务属于核心服务,并且是与动画相关的服务。
  • user graphics: 指定服务运行的用户为"graphics"。
  • group graphics audio: 指定服务运行的组为"graphics audio",表示具有这两个组的权限。
  • disabled: 表示此服务当前处于禁用状态,不会自动启动。
  • oneshot: 表示此服务只执行一次,完成任务后即退出。
  • ioprio rt 0: 设置了I/O调度优先级。
  • task_profiles MaxPerformance: 指定了任务的性能规格为最大性能。

根据你提供的信息,开机动画服务当前处于禁用状态,不会自动启动。

启动开机动画

开机动画在SurfaceFlinger初始化完成之后播放

//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {............//启动mStartPropertySetThread线程播放开机动画mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);if (mStartPropertySetThread->Start() != NO_ERROR) {ALOGE("Run StartPropertySetThread failed!");}
}

那么看看StartPropertySetThread线程中具体如何运行

//frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp
bool StartPropertySetThread::threadLoop() {// Set property service.sf.present_timestamp, consumer need check its readinessproperty_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");// Clear BootAnimation exit flagproperty_set("service.bootanim.exit", "0");property_set("service.bootanim.progress", "0");// Start BootAnimation if not startedproperty_set("ctl.start", "bootanim");// Exit immediatelyreturn false;
}

StartPropertySetThread中通过设置属性方式启动动画播放。

所以如果需要手动运行bootanimation, 需要通过下面命令完成:

setprop service.bootanim.exit 0
setprop ctl.start bootanim

接下来我们进入bootanimation实现的代码分析动画播放的具体流程。

动画播放流程

  1. 首先从main函数分析,开机动画运行在一个线程中
//frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main()
{
sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());
waitForSurfaceFlinger();
boot->run("BootAnimation", PRIORITY_DISPLAY);
}
  1. 找寻开机动画文件
//frameworks/base/cmds/bootanimation/BootAnimation.cpp
void BootAnimation::onFirstRef() {......preloadAnimation();......
}
bool BootAnimation::preloadAnimation() {//查找开机动画findBootAnimationFile();if (!mZipFileName.isEmpty()) {//加载开机动画mAnimation = loadAnimation(mZipFileName);return (mAnimation != nullptr);}return false;
}
//找寻开机动画文件主要流程即在该函数中完成
void BootAnimation::findBootAnimationFile() {......//加密设备开机动画路径static const std::vector<std::string> encryptedBootFiles = {PRODUCT_ENCRYPTED_BOOTANIMATION_FILE, SYSTEM_ENCRYPTED_BOOTANIMATION_FILE,};// 启动动画路径static const std::vector<std::string> bootFiles = {APEX_BOOTANIMATION_FILE, playDarkAnim ? PRODUCT_BOOTANIMATION_DARK_FILE : PRODUCT_BOOTANIMATION_FILE,OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};   ......    
}
  1. 加载开机动画文件并解析desc文件
//frameworks/base/cmds/bootanimation/BootAnimation.cpp
BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn) {if (mLoadedFiles.indexOf(fn) >= 0) {SLOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",fn.string());return nullptr;}ZipFileRO *zip = ZipFileRO::open(fn);if (zip == nullptr) {SLOGE("Failed to open animation zip \"%s\": %s",fn.string(), strerror(errno));return nullptr;}ALOGD("%s is loaded successfully", fn.string());//解析bootanimation.zip并填充AnimationAnimation *animation =  new Animation;animation->fileName = fn;animation->zip = zip;animation->clockFont.map = nullptr;mLoadedFiles.add(animation->fileName);//解析desc.txt文件并填充Animation对象parseAnimationDesc(*animation);if (!preloadZip(*animation)) {releaseAnimation(animation);return nullptr;}mLoadedFiles.remove(fn);return animation;
}
  1. 初始化显示参数
//frameworks/base/cmds/bootanimation/BootAnimation.cpp
status_t BootAnimation::readyToRun() {//设置分辨率、创建Surface等
ui::Size resolution = displayMode.resolution;resolution = limitSurfaceSize(resolution.width, resolution.height);// create the native surfacesp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);}// initialize opengl and eglEGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);eglInitialize(display, nullptr, nullptr);
  1. 进入最终播放流程
//frameworks/base/cmds/bootanimation/BootAnimation.cpp
bool BootAnimation::threadLoop() {bool result;initShaders();// 初始化着色器// 为启动视频功能进行初始化mStartbootanimaTime = 0;mBootVideoTime = -1;//Android还支持播放视频文件,这样可以方便广告植入,开展开机广告业务if (mVideoAnimation) {result = video();} else {// 如果没有启动动画文件,那么使用默认的安卓logo动画。if (mZipFileName.isEmpty()) {ALOGD("No animation file");result = android();} else {result = movie();}}// 关闭回调mCallbacks->shutdown();eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);eglDestroyContext(mDisplay, mContext);eglDestroySurface(mDisplay, mSurface);mFlingerSurface.clear();mFlingerSurfaceControl.clear();eglTerminate(mDisplay);eglReleaseThread();IPCThreadState::self()->stopProcess();return result;
}bool BootAnimation::movie() {if (mAnimation == nullptr) {mAnimation = loadAnimation(mZipFileName);}......playAnimation(*mAnimation);......releaseAnimation(mAnimation);......
}bool BootAnimation::playAnimation(const Animation& animation) {const size_t pcount = animation.parts.size();nsecs_t frameDuration = s2ns(1) / animation.fps;for (size_t i=0 ; i<pcount ; i++) {const Animation::Part& part(animation.parts[i]);const size_t fcount = part.frames.size();// Handle animation packageif (part.animation != nullptr) {playAnimation(*part.animation);if (exitPending())break;continue; //to next part}/////使用gl绘制每一帧的图像//第2轮及以后的播放if (r > 0) {glBindTexture(GL_TEXTURE_2D, frame.tid);} else {//第一轮播放需要初始化glGenTextures(1, &frame.tid);glBindTexture(GL_TEXTURE_2D, frame.tid);int w, h;// Set decoding option to alpha unpremultiplied so that the R, G, B channels// of transparent pixels are preserved.initTexture(frame.map, &w, &h, false /* don't premultiply alpha */);}////}
}

动画退出时机

//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private void performEnableScreen() {////if (!mBootAnimationStopped) {Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);// stop boot animation// formerly we would just kill the process, but we now ask it to exit so it// can choose where to stop the animation.SystemProperties.set("service.bootanim.exit", "1");mBootAnimationStopped = true;}///
}

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

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

相关文章

基于深度学习的超分辨率图像技术一览

超分辨率(Super-Resolution)即通过硬件或软件的方法提高原有图像的分辨率&#xff0c;图像超分辨率是计算机视觉和图像处理领域一个非常重要的研究问题&#xff0c;在医疗图像分析、生物特征识别、视频监控与安全等实际场景中有着广泛的应用。 SR取得了显著进步。一般可以将现有…

小机器人,电子锁,牙刷,表类开关,磁阀开关等一些安防直流驱动的选型介绍分析 5V,大电流,小封装

安防监控是一门被人们日益重视的新兴行业&#xff0c;就目前发展来看&#xff0c;应用普及程度越来越广&#xff0c;科技含量也越来越高&#xff0c;几乎所有高新科技都可促进其发展&#xff0c;尤其是信息时代的来临&#xff0c;更为该行业的发展提供契机。其中安防领域最为典…

【力扣】刷题备忘录-动归-62. 不同路径

62. 不同路径 class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m,vector<int>(n,0));// 2D vector的标准写法 有些麻烦for (int i 0; i < m; i) dp[i][0] 1; // 又忘记写&#xff1b;了。。。for (int j 0; j < …

Blackmagic Design Fusion Studio 18 – 创意视觉特效的全能工具!

无论您是电影制片人、电视广告创作者还是视觉特效艺术家&#xff0c;Blackmagic Design Fusion Studio 18 都是您的完美选择。这款全能视觉特效软件为您提供了无限的创意可能性&#xff0c;助力您打造令人惊叹的视觉效果。 Blackmagic Design Fusion Studio 18 的卓越功能&…

【PWN】学习笔记(二)【栈溢出基础】

目录 课程教学C语言函数调用栈ret2textPWN工具 课程教学 课程链接&#xff1a;https://www.bilibili.com/video/BV1854y1y7Ro/?vd_source7b06bd7a9dd90c45c5c9c44d12e7b4e6 课程附件&#xff1a; https://pan.baidu.com/s/1vRCd4bMkqnqqY1nT2uhSYw 提取码: 5rx6 C语言函数调…

Doocker还原容器启动命令参数

get_command_4_run_container可以还原docker执行命令, 这是个第三方包&#xff0c;需要先安装&#xff1a; docker pull cucker/get_command_4_run_container 命令格式&#xff1a; docker run --rm -v /var/run/docker.sock:/var/run/docker.sock cucker/get_command_4_run…

MISRA C++ 2023:C和C++测试解决方案实现静态分析

自动化软件测试解决方案的全球领导者Parasoft今天宣布&#xff0c;随着Parasoft C/Ctest 2023.2即将发布&#xff0c;全面支持MISRA C 2023。Parasoft针对C和C软件开发的完全集成测试解决方案计划于2023年12月发布&#xff0c;可以帮助团队实现自动化静态分析和编码标准合规性&…

Windows 安全基础——NetBIOS篇

Windows 安全基础——NetBIOS篇 1. NetBIOS简介 NetBIOS&#xff08;Network Basic Input/Output System, 网络基本输入输出系统&#xff09;是一种接入服务网络的接口标准。主机系统通过WINS服务、广播及lmhosts文件多种模式&#xff0c;把NetBIOS名解析对应的IP地址&#xf…

Windows安装Maven

一、Maven 是什么&#xff1f; Maven 是一个项目管理和整合工具。Maven 为开发者提供了一套完整的构建生命周期框架。开发团队几乎不用花多少时间就能够自动完成工程的基础构建配置&#xff0c;因为 Maven 使用了一个标准的目录结构和一个默认的构建生命周期。 在有多个开发团…

AirServer Mac7.27中文破解2024最新图文安装激活教程含许可证

AirServer Mac 7.27中文破解是一款便捷式投屏软件&#xff0c;它的主要功能在于实时地将移动设备上的图像画面内容投放到电脑设备上&#xff0c;让电脑成为iPad、iPhone等iOS系统设备的大屏显示器。 在设备之间建立局域网内的信号发送与接收通道&#xff0c;确保数据可以稳定安…

pytorch 常用api笔记

view_as()函数 函数定义&#xff1a;view_as(tensor) [参数为一个Tensor张量] 该函数的作用是将调用函数的变量&#xff0c;转变为同参数tensor同样的形状。 例子 data1 [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 0], [10, 11]]] t1 torch.Tensor(data1).long() # size2…

【解刊】IEEE(trans),1区TOP,CCF-B,审稿国人友好,最快仅1个月录用!值得收藏~

计算机类 • 好刊解读 今天小编带来IEEE旗下计算机领域高分好刊&#xff0c;CCF-B类推荐的期刊解读&#xff0c;期刊审稿快&#xff0c;投稿友好&#xff0c;如您有投稿需求&#xff0c;可作为重点关注&#xff01;后文有相关领域真实发表案例&#xff0c;供您投稿参考~ 01 期…

1,使用IDLE开启我们第一个Python程序

前面我们已经安装好了Python&#xff0c;安装了Python后&#xff0c;他会自动帮我们安装一个IDLE。IDLE是一个Python自带的非常简洁的集成开发环境&#xff08;IDE&#xff09;。他是一个Python Shell&#xff0c;我们可以利用Python Shell与Python交互。下面我们就利用IDLE开发…

跟风申请香港优才计划的人,很容易进入骗局和被割韭菜!

跟风申请香港优才计划的人&#xff0c;很容易进入骗局和被割韭菜&#xff01; 不得不承认一个事实就是&#xff0c;越来越多内地人正在抢占申请香港身份的份额&#xff01;就因为这个项目门槛低、投入低&#xff0c;简单来说就是多一层身份&#xff0c;多一层福利保障。 从目前…

Kubernetes实战(九)-kubeadm安装k8s集群

1 环境准备 1.1 主机信息 iphostname10.220.43.203master10.220.43.204node1 1.2 系统信息 $ cat /etc/redhat-release Alibaba Cloud Linux (Aliyun Linux) release 2.1903 LTS (Hunting Beagle) 2 部署准备 master/与slave主机均需要设置。 2.1 设置主机名 # master h…

成都工业学院Web技术基础(WEB)实验五:CSS3动画制作

写在前面 1、基于2022级计算机大类实验指导书 2、代码仅提供参考&#xff0c;前端变化比较大&#xff0c;按照要求&#xff0c;只能做到像&#xff0c;不能做到一模一样 3、图片和文字仅为示例&#xff0c;需要自行替换 4、如果代码不满足你的要求&#xff0c;请寻求其他的…

使用PyTorch II的新特性加快LLM推理速度

Pytorch团队提出了一种纯粹通过PyTorch新特性在的自下而上的优化LLM方法&#xff0c;包括: Torch.compile: PyTorch模型的编译器 GPU量化:通过降低精度操作来加速模型 推测解码:使用一个小的“草稿”模型来加速llm来预测一个大的“目标”模型的输出 张量并行:通过在多个设备…

成都工业学院Web技术基础(WEB)实验三:CSS字体等属性使用

写在前面 1、基于2022级计算机大类实验指导书 2、代码仅提供参考&#xff0c;前端变化比较大&#xff0c;按照要求&#xff0c;只能做到像&#xff0c;不能做到一模一样 3、图片和文字仅为示例&#xff0c;需要自行替换 4、如果代码不满足你的要求&#xff0c;请寻求其他的…

rails3 row sql example

refer: https://stackoverflow.com/questions/14824453/rails-raw-sql-example 搜索怎么在Rails3 使用row sql&#xff0c; 打开上面的链接&#xff0c;可以找到这样的答案&#xff0c;如下图&#xff1a; sql "Select * from ... your sql query here" records_ar…

Nginx的server层外层的常见配置语句的解读

有下面的Nginx配置: worker_processes auto; worker_rlimit_nofile 51200;events {use epoll;worker_connections 51200;multi_accept on; }http {include mime.types;default_type application/octet-stream;server_names_hash_bucket_size 512;client_max_body_size 50m;cli…