Android系统开发进阶-BootAnimation添加视频播放功能
对于手机用户来说,开机动画接触得比较少,因为用户可能一年也不会关开机一次。但对于 TV 设备跟盒子的用户来说,开机动画就是家常便饭了,每天都要开关机。反正都是要等待开机,看 Android logo 是看,看广告也是看,所以各厂商也就利用这个来顺便赚个广告费。Android 系统默认的开机动画只支持图片形式的动画,是不支持 mp4 等视频类型的,但我们的广告又是以视频为主的。所以我们需要给 BootAnimation 增加播放视频的功能,下面我们就来演示一下怎么实现这个功能。
1. BootAnimation 类添加 video 播放函数
BootAnimation.h
1 2 3 4 5
| bool android(); bool movie();
bool video();
|
BootAnimation.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include <media/mediaplayer.h> #include <media/IMediaHTTPService.h>
const char *videoPath = "/system/media/bootvideo.mp4"; bool BootAnimation::video() { const float MAX_FPS = 60.0f; const float CHECK_DELAY = ns2us(s2ns(1) / MAX_FPS); eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(mDisplay, mSurface); sp<MediaPlayer> mp = new MediaPlayer(); mp->reset(); mp->setDataSource(NULL, videoPath, NULL); mp->setVideoSurfaceTexture(mFlingerSurface->getIGraphicBufferProducer()); mp->prepare(); mp->start(); mp->setVolume(1.0, 1.0);
while(true) { if(exitPending()) { break; } usleep(CHECK_DELAY); checkExit(); }
while (mp->isPlaying()) { usleep(200000); } ALOGD("bootvideo play finish");
mp->stop(); mp->disconnect(); mp.clear(); return true; }
bool BootAnimation::threadLoop() { if (access(videoPath, R_OK) == 0) { video(); } else if (!mZipFileName.isEmpty()) { movie(); } else { android(); } ... }
|
2. 添加依赖
因为我们要用到 MediaPlayer, 所以需要添加 libmedia 依赖:
Android.bp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| cc_library_shared { name: "libbootanimation", defaults: ["bootanimation_defaults"],
srcs: ["BootAnimation.cpp"],
shared_libs: [ "libui", "libhwui", "libEGL", "libGLESv1_CM", "libgui", "libtinyalsa", "libmedia", ],
product_variables: { product_is_iot: { init_rc: ["iot/bootanim_iot.rc"], }, }, }
|
3. selinux 设置
selinux 的配置都是在执行后,看报什么错误,就加什么权限,最后需要给 bootanim 服务和 mediaserver 服务添加权限,直接看 diff 吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| qiushao@qiushao-pc:~/source/android-10/system/sepolicy$ git diff . diff --git a/prebuilts/api/29.0/public/bootanim.te b/prebuilts/api/29.0/public/bootanim.te index e8cb98bbc..0b1ffd3ee 100644 --- a/prebuilts/api/29.0/public/bootanim.te +++ b/prebuilts/api/29.0/public/bootanim.te @@ -8,6 +8,7 @@ hal_client_domain(bootanim, hal_graphics_composer) binder_use(bootanim) binder_call(bootanim, surfaceflinger) +binder_call(bootanim, mediaserver) binder_call(bootanim, audioserver) hwbinder_use(bootanim) @@ -23,6 +24,7 @@ allow bootanim audio_device:chr_file rw_file_perms; allow bootanim audioserver_service:service_manager find; allow bootanim surfaceflinger_service:service_manager find; +allow bootanim mediaserver_service:service_manager find; # Allow access to ion memory allocation device allow bootanim ion_device:chr_file rw_file_perms; diff --git a/prebuilts/api/29.0/public/mediaserver.te b/prebuilts/api/29.0/public/mediaserver.te index 70d0a55b2..5a9d8fef0 100644 --- a/prebuilts/api/29.0/public/mediaserver.te +++ b/prebuilts/api/29.0/public/mediaserver.te @@ -24,6 +24,7 @@ userdebug_or_eng(` binder_use(mediaserver) binder_call(mediaserver, binderservicedomain) binder_call(mediaserver, appdomain) +binder_call(mediaserver, bootanim) binder_service(mediaserver) allow mediaserver media_data_file:dir create_dir_perms; diff --git a/public/bootanim.te b/public/bootanim.te index e8cb98bbc..0b1ffd3ee 100644 --- a/public/bootanim.te +++ b/public/bootanim.te @@ -8,6 +8,7 @@ hal_client_domain(bootanim, hal_graphics_composer) binder_use(bootanim) binder_call(bootanim, surfaceflinger) +binder_call(bootanim, mediaserver) binder_call(bootanim, audioserver) hwbinder_use(bootanim) @@ -23,6 +24,7 @@ allow bootanim audio_device:chr_file rw_file_perms; allow bootanim audioserver_service:service_manager find; allow bootanim surfaceflinger_service:service_manager find; +allow bootanim mediaserver_service:service_manager find; # Allow access to ion memory allocation device allow bootanim ion_device:chr_file rw_file_perms; diff --git a/public/mediaserver.te b/public/mediaserver.te index 70d0a55b2..5a9d8fef0 100644 --- a/public/mediaserver.te +++ b/public/mediaserver.te @@ -24,6 +24,7 @@ userdebug_or_eng(` binder_use(mediaserver) binder_call(mediaserver, binderservicedomain) binder_call(mediaserver, appdomain) +binder_call(mediaserver, bootanim) binder_service(mediaserver) allow mediaserver media_data_file:dir create_dir_perms; qiushao@qiushao-pc:~/source/android-10/system/sepolicy$
|
4. bootvideo 预置
我们把 bootvideo.mp4 视频文件放到 device/qiushao/pure/bootvideo.mp4, 我测试用的 bootvideo.mp4
然后在 pure.mk 中添加以下配置:
1
| PRODUCT_COPY_FILES += device/qiushao/pure/bootvideo.mp4:system/media/bootvideo.mp4
|
5. 编译验证
以上就完成了 BootAnimation 播放视频的功能,其实也很简单,就是调用一下 MediaPlayer 的 c++ 接口而已。音量设置也是可以的。
我们编译验证一下,图像声音都是正常的。