Android静态壁纸功能实现参与的类
/frameworks/base/core/java/android/app/WallpaperManager.java
给开发者提供方法调用。例:setBitmap()/getBitmap()
/frameworks/base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
系统服务,管理壁纸的运行和切换,由SystemServer启动
/frameworks/base/core/java/android/service/wallpaper/WallpaperService.java
Android壁纸服务,ImageWallpaper的父类
/frameworks/base/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
Android设定的壁纸服务,如果default_wallpaper_component没指定,则使用image_wallpaper_component指定的ImageWallpaper
开机壁纸加载流程
1.SystemServer.java -> startOtherServices()内通过config_enableWallpaperService该布尔值判断是否启动壁纸服务:
if (context.getResources().getBoolean(R.bool.config_enableWallpaperService)) {
traceBeginAndSlog("StartWallpaperManagerService");
mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
traceEnd();
}
服务准备就绪后进行初始化操作,WallpaperManagerService.java->initialize()
void initialize() {
mMonitor.register(mContext, null, UserHandle.ALL, true);
getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
// Initialize state from the persistent store, then guarantee that the
// WallpaperData for the system imagery is instantiated & active, creating
// it from defaults if necessary.
loadSettingsLocked(UserHandle.USER_SYSTEM, false);
getWallpaperSafeLocked(UserHandle.USER_SYSTEM, FLAG_SYSTEM);
}
2.WallpaperManagerService.java->getWallpaperDir()
getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
创建系统用户目录/data/system/users/0/,其目录下在壁纸显示后会生成wallpaper_info.xml文件,用于存放壁纸的宽度、高度、壁纸存放位置等信息。
3.WallpaperManagerService.java->loadSettingsLocked()
该方法内开头包括了wallpaper_info文件的创建(JounrnaledFile类)、壁纸文件wallpaper(WallpaperData)的生成、wallpaper_info文件的解析(XmlPullParser)。
loadSettingsLocked(){
```
if (!success) {
wallpaper.width = -1;
wallpaper.height = -1;
wallpaper.cropHint.set(0, 0, 0, 0);
wallpaper.padding.set(0, 0, 0, 0);
wallpaper.name = "";
// wallpaper.name = "res:com.xxxx.xxxxx:drawable/wallpaper_bg_dark_normal_1";
mLockWallpaperMap.remove(userId);
} else {
if (wallpaper.wallpaperId <= 0) {
wallpaper.wallpaperId = makeWallpaperIdLocked();
if (DEBUG) {
Slog.w(TAG, "Didn't set wallpaper id in loadSettingsLocked(" + userId
+ "); now " + wallpaper.wallpaperId);
}
}
}
ensureSaneWallpaperData(wallpaper);
```
}
由于首次启动时不存在wallpaper_info.xml,所以success为false,开始初始化wallpaperData属性,并调用ensureSaneWallpaperData()方法通过WindowManager.getDefaultDisplay.getMaximumSizeDimension()获取屏幕最大尺寸作为壁纸宽高。
4.WallpaperManagerService.java->switchUser()
开启WallpaperObserver和ThemeSettingsObserver监听,观测切换壁纸和主题操作
5.WallpaperManagerService.java->bindWallpaperComponentLocked()
拉起壁纸服务,默认为ImageWallpaper。并向WMS申请用于添加壁纸窗口的窗口令牌。后续这一部分主要由WallpaperConnection.onServiceConnected()回调中处理。
6.WallpaperManagerService.java->attachServiceLocked()
在方法内调用IWallpaperServiceWrapper的attach方法,将创建壁纸窗体需要的信息给到WallpaperService。
void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
try {
conn.mService.attach(conn, conn.mToken,
TYPE_WALLPAPER, false,
wallpaper.width, wallpaper.height, wallpaper.padding);
} catch (RemoteException e) {
Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
if (!wallpaper.wallpaperUpdating) {
bindWallpaperComponentLocked(null, false, false, wallpaper, null);
}
}
}
7.WallpaperService-IWallpaperServiceWrapper.attach()
构造IWallpaperEngineWrapperService实例,并在方法内发送DO_ATTACH信息。
8.WallpaperService.java->executeMessage()
public void executeMessage(Message message) {
switch (message.what) {
case DO_ATTACH: {
try {
mConnection.attachEngine(this);
} catch (RemoteException e) {
Log.w(TAG, "Wallpaper host disappeared", e);
return;
}
Engine engine = onCreateEngine();
mEngine = engine;
mActiveEngines.add(engine);
engine.attach(this);
return;
}
....
WallpaperConnection保存IWallpaperEngineWrapper实例,无需担心被回收,而且WallpaperManagerService还可以通过它与实际Engine进行通信。之后再创建Engine对象,Engine是真正的壁纸实现。
engine.attach()方法内也进行壁纸绘制。
9.updataSurfaceSize()->loadWallpaper()->mWallpaperManager.getBitmap()
通过getBitmap()方法获取。
10.WallpaperManager.java->openDefaultWallpaper()
public static InputStream openDefaultWallpaper(Context context, @SetWallpaperFlags int which) {
final String whichProp;
final int defaultResId;
if (which == FLAG_LOCK) {
/* Factory-default lock wallpapers are not yet supported
whichProp = PROP_LOCK_WALLPAPER;
defaultResId = com.android.internal.R.drawable.default_lock_wallpaper;
*/
return null;
} else {
whichProp = PROP_WALLPAPER;
defaultResId = com.android.internal.R.drawable.default_wallpaper;
}
//不走buildinfo.sh文件读取默认属性值,且该文件的ro.config.wallpaper属性已经丢失
final String path = SystemProperties.get(whichProp);
if (!TextUtils.isEmpty(path)) {
final File file = new File(path);
if (file.exists()) {
try {
return new FileInputStream(file);
} catch (IOException e) {
//Ignored, fall back to platform default below
}
}
}
try {
return context.getResources().openRawResource(defaultResId);
} catch (NotFoundException e) {
// no default defined for this device; this is not a failure
}
return null;
}
在此有frameworks/base/core/res/res/drawable 下提供壁纸资源,通过context.gerResource().openRawResource()返回,在getDefaultWallpaper()中转成bitmap交由ImageWallpaper的drawFrame()进行绘制