1、通过调用WallpaperManager的setWallpaperComponent方法可以帮我们开启自定义动态壁纸。
frameworks/base/core/java/android/app/WallpaperManager.java
public class WallpaperManager {
@SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
public boolean setWallpaperComponent(ComponentName name) {
return setWallpaperComponent(name, mContext.getUserId());
}
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
@UnsupportedAppUsage
public boolean setWallpaperComponent(ComponentName name, int userId) {
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
}
try {
//通过binder调用WallpaperManagerService的setWallpaperComponentChecked方法
sGlobals.mService.setWallpaperComponentChecked(name, mContext.getOpPackageName(),
userId);
return true;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private static class Globals extends IWallpaperManagerCallback.Stub {
private final IWallpaperManager mService;//WallpaperManagerService的binder代理对象
}
}
类型为Globals的sGlobals对象,内部属性mService是一个代理者,setWallpaperComponent最终会调用WallpaperManagerService的setWallpaperComponentChecked方法。
2、WallpaperManagerService的setWallpaperComponentChecked方法如下所示。
frameworks/base/core/java/android/app/WallpaperManager.java
public class WallpaperManagerService extends IWallpaperManager.Stub
implements IWallpaperManagerService {
@Override
public void setWallpaperComponentChecked(ComponentName name, String callingPackage,
int userId) {
//权限验证
if (isWallpaperSupported(callingPackage) && isSetWallpaperAllowed(callingPackage)) {
setWallpaperComponent(name, userId);
}
}
//设置动态壁纸
private void setWallpaperComponent(ComponentName name, int userId) {
userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
false /* all */, true /* full */, "changing live wallpaper", null /* pkg */);
//权限检测
checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
int which = FLAG_SYSTEM;
boolean shouldNotifyColors = false;
WallpaperData wallpaper;//壁纸数据
synchronized (mLock) {
Slog.v(TAG, "setWallpaperComponent name=" + name);
wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
}
final long ident = Binder.clearCallingIdentity();
// Live wallpapers can't be specified for keyguard. If we're using a static
// system+lock image currently, migrate the system wallpaper to be a lock-only
// image as part of making a different live component active as the system
// wallpaper.
if (mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
if (mLockWallpaperMap.get(userId) == null) {
// We're using the static imagery and there is no lock-specific image in place,
// therefore it's a shared system+lock image that we need to migrate.
Slog.i(TAG, "Migrating current wallpaper to be lock-only before"
+ "updating system wallpaper");
migrateSystemToLockWallpaperLocked(userId);
}
}
// New live wallpaper is also a lock wallpaper if nothing is set
if (mLockWallpaperMap.get(userId) == null) {
which |= FLAG_LOCK;
}
try {
wallpaper.imageWallpaperPending = false;
boolean same = changingToSame(name, wallpaper);
//启动新壁纸的WallpaperService
if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
if (!same) {
wallpaper.primaryColors = null;
} else {
if (wallpaper.connection != null) {
wallpaper.connection.forEachDisplayConnector(displayConnector -> {
try {
if (displayConnector.mEngine != null) {
displayConnector.mEngine.dispatchWallpaperCommand(
COMMAND_REAPPLY, 0, 0, 0, null);
}
} catch (RemoteException e) {
Slog.w(TAG, "Error sending apply message to wallpaper", e);
}
});
}
}
wallpaper.wallpaperId = makeWallpaperIdLocked();
notifyCallbacksLocked(wallpaper);
shouldNotifyColors = true;
}
} finally {
Binder.restoreCallingIdentity(ident);
}
}
if (shouldNotifyColors) {
notifyWallpaperColorsChanged(wallpaper, which);
notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
}
}
}
参考文章:https://www.kancloud.cn/wizardforcel/deepin-android-vol3/122360
https://www.freesion.com/article/6656482862/