概述
智能手机的开机画面一般是由一帧静态图片或者一组静态图片组成。一组动态图片可以在代码中实现开机动画的效果。为了丰富开机界面的形式,百变开机画面补充了这样的需求。
可以实现开机播放自定义视频,又可以兼容开机播放静态图片的功能。
该功能主要由两个bin服务实现
Counter服务是属于系统bin服务,位置在/system/bin/counter,拥有系统权限,可以读写系统file,实现开机画面的倒计时功能与开机静态图片的展示。
Play服务是属于系统bin服务,位置在/system/bin/counter,拥有系统权限,可以读写系统file,实现开机自定义视频功能,可以支持mp4,ts等常见视频格式
类Counte实现
counter.cpp是一个显性的倒计时提示,在用户自定义的开机视频和开机画面上显示剩余秒数提示用户,同时如果有静态图片,背景显示图片。
1. Counter是系统bin服务,通过createSurface创建实例作为图层:
status_t Counter::readyToRun() {
//获取内建显示设备
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
DisplayInfo dinfo;
//获取默认的Display对象参数
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
if (status)
return -1;
// 创建native SurfaceView
sp<SurfaceControl> control = session()->createSurface(String8(“Counter”),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888, 0);
//操作SurfaceComposeClient,并设置图层优先级
SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000002);
SurfaceComposerClient::closeGlobalTransaction();
sp<Surface> s = control->getSurface();
// 初始化 opengl 和 egl引擎参数
const EGLint attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 0,
EGL_NONE
};
2. 加载系统默认UI资源,通过decodeImage来解码图片,并显示在SurfaceLayer之上。
status_t Counter::initTexture(Texture* texture, AssetManager& assets,
const char* name) {
//声明bitmap对象
SkBitmap bitmap;
//通过sk库函数对图片进行decode
SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
&bitmap, kUnknown_SkColorType, SkImageDecoder::kDecodePixels_Mode);
//assert对象关闭,释放资源
asset->close();
delete asset;
……
}
类Player.cpp 实现
Player.cpp是检查data目录下是否有视频文件,通过在开机界面绘制surfaceview来播放视频。
在surfacelinger服务初始化完成后,启动Player服务,创建surface示例并设置初始化view参数。这部分与初始化Counter过程一样,需要创建Native Surface。
检测目录下视频文件后,开始调用MediaPlayer播放视频,获取视频时长,格式,设置倒计时服务,直到播放结束后进入系统。
播放视频相关代码流程:
int main(int argc, char **argv) {
android::ProcessState::self()->startThreadPool();
//初始化SurfaceComposerClient
sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
//获取内建显示设备
sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
//创建Surface,初始化相关参数
sp<SurfaceControl> control =
composerClient->createSurface(
String8(“A Surface”),
displayWidth,
displayHeight,
PIXEL_FORMAT_RGB_565,
0);
SurfaceComposerClient::closeGlobalTransaction();
//创建MediaPlayer实例
sp<IMediaPlayer> player =
service->create(client, AUDIO_SESSION_ALLOCATE);
//设置播放源目标
if (player != NULL && player->setDataSource(source) == NO_ERROR) {
//设置播放Video的SurfaceTexture,用于显示播放视频流
player->setVideoSurfaceTexture(surface->getIGraphicBufferProducer());
//开始播放文件
player->start();
client->waitForEOS();
//播放停止
player->stop();
} else {
fprintf(stderr, “failed to instantiate player./n”);
}
//关闭composerClient
composerClient->dispose();
}
播放自定义视频流程
Counter与Player加载分析:
在init.rc中添加counter与advert服务,user权限声明为root,初次启动设置为disabled,需要主动调起。
service connter /system/bin/counter
class core
user root
group graphics audio
disabled
oneshot
service player /system/bin/player
class core
user root
group graphics audio
disabled
oneshot
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/192415.html