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.pswp.cn/news/213536.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/213536.shtml
英文地址,請注明出處:http://en.pswp.cn/news/213536.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于深度學習的超分辨率圖像技術一覽

超分辨率(Super-Resolution)即通過硬件或軟件的方法提高原有圖像的分辨率&#xff0c;圖像超分辨率是計算機視覺和圖像處理領域一個非常重要的研究問題&#xff0c;在醫療圖像分析、生物特征識別、視頻監控與安全等實際場景中有著廣泛的應用。 SR取得了顯著進步。一般可以將現有…

【知識分享】SpringBoot自定義bean

在Spring Boot中&#xff0c;可以使用注解和配置來定義自定義的Bean。以下是自定義Bean的詳細講解和代碼示例&#xff1a; 1.使用注解定義自定義Bean&#xff1a; 在你的自定義類上添加Component或其衍生注解&#xff08;如Service、Repository等&#xff09;&#xff0c;將該…

小機器人,電子鎖,牙刷,表類開關,磁閥開關等一些安防直流驅動的選型介紹分析 5V,大電流,小封裝

安防監控是一門被人們日益重視的新興行業&#xff0c;就目前發展來看&#xff0c;應用普及程度越來越廣&#xff0c;科技含量也越來越高&#xff0c;幾乎所有高新科技都可促進其發展&#xff0c;尤其是信息時代的來臨&#xff0c;更為該行業的發展提供契機。其中安防領域最為典…

docker 容器內數據映射到容器外

es 暴露的端口很多 es 十分的耗內存 es 的數據一般需要放置到安全目錄&#xff01;掛載 啟動elasticsearch [rootiZbp1guc0wov85gocdqeaiZ home]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" elasticsearch:…

【力扣】刷題備忘錄-動歸-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 < …

Python實現的一個簡單的GAN(生成對抗網絡)例子

一個簡單的GAN&#xff08;生成對抗網絡&#xff09;例子 以下是使用Python實現的一個簡單的GAN&#xff08;生成對抗網絡&#xff09;例子&#xff0c;它可以生成手寫數字圖像 python # Importing libraries import numpy as np import matplotlib.pyplot as plt from tenso…

【Docker】Docker的安裝部署及優化詳解

一、部署20版本的docker docker初期版本是1.13(同一版本,開源) ——》分類型 1.15 - 1.17 過程中分成兩種。 開源社區 docker-ce 企業版 docker-ee 目前 Docker 只能支持 64 位系統。 #關閉防火墻 systemctl stop firewalld.service setenforce 0 1.1 安裝依賴包 yum instal…

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;可以幫助團隊實現自動化靜態分析和編碼標準合規性&…

git報錯WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

git報錯WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 可能存在的情況是&#xff1a;連接的gitlab服務已經切換物理服務器。除了上述的可能性還可以參考以下 Git Pull FailedWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! IT IS POSSIBLE THAT SOMEONE IS DOING …

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開發…

常用的調試方法(段錯誤產生原因)

C 語言中常用的調試技巧和 demo C語言中常用的調試方法 打印調試信息 GDB 調試器 編寫單元測試 段錯誤產生原因 初學時兩種常用的段錯誤調試方法 C 語言中常用的調試技巧和 demo 當程序員進行調試時&#xff0c;他們通常會使用一些調試語句或技巧來幫助他們理解代碼的執行過程…

跟風申請香港優才計劃的人,很容易進入騙局和被割韭菜!

跟風申請香港優才計劃的人&#xff0c;很容易進入騙局和被割韭菜&#xff01; 不得不承認一個事實就是&#xff0c;越來越多內地人正在搶占申請香港身份的份額&#xff01;就因為這個項目門檻低、投入低&#xff0c;簡單來說就是多一層身份&#xff0c;多一層福利保障。 從目前…