Merge "Lock screen LWP: use WallpaperService for lock screen."
This commit is contained in:
committed by
Android (Google) Code Review
commit
2dd68fbcd9
@@ -122,6 +122,10 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen
|
||||
public LoaderResult loadBitmap(int currentUserId, UserHandle selectedUser) {
|
||||
// May be called on any thread - only use thread safe operations.
|
||||
|
||||
if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) {
|
||||
return LoaderResult.success(null);
|
||||
}
|
||||
|
||||
if (!mWallpaperManager.isWallpaperSupported()) {
|
||||
// When wallpaper is not supported, show the system wallpaper
|
||||
return LoaderResult.success(null);
|
||||
|
||||
@@ -55,6 +55,12 @@ class WallpaperData {
|
||||
*/
|
||||
int mWhich;
|
||||
|
||||
/**
|
||||
* True if the system wallpaper was also used for lock screen before this wallpaper was set.
|
||||
* This is needed to update state after setting the wallpaper.
|
||||
*/
|
||||
boolean mSystemWasBoth;
|
||||
|
||||
/**
|
||||
* Callback once the set + crop is finished
|
||||
*/
|
||||
@@ -139,6 +145,61 @@ class WallpaperData {
|
||||
(wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_CROP : WALLPAPER_CROP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the essential properties of a WallpaperData to a new instance, including the id and
|
||||
* WallpaperConnection, usually in preparation for migrating a system+lock wallpaper to system-
|
||||
* or lock-only. NB: the source object retains the pointer to the connection and it is the
|
||||
* caller's responsibility to set this to null or otherwise be sure the connection is not shared
|
||||
* between WallpaperData instances.
|
||||
*
|
||||
* @param source WallpaperData object to copy
|
||||
*/
|
||||
WallpaperData(WallpaperData source) {
|
||||
this.userId = source.userId;
|
||||
this.wallpaperFile = source.wallpaperFile;
|
||||
this.cropFile = source.cropFile;
|
||||
this.wallpaperComponent = source.wallpaperComponent;
|
||||
this.mWhich = source.mWhich;
|
||||
this.wallpaperId = source.wallpaperId;
|
||||
this.cropHint.set(source.cropHint);
|
||||
this.allowBackup = source.allowBackup;
|
||||
this.primaryColors = source.primaryColors;
|
||||
this.mWallpaperDimAmount = source.mWallpaperDimAmount;
|
||||
this.connection = source.connection;
|
||||
this.connection.mWallpaper = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder out = new StringBuilder(defaultString(this));
|
||||
out.append(", id: ");
|
||||
out.append(wallpaperId);
|
||||
out.append(", which: ");
|
||||
out.append(mWhich);
|
||||
out.append(", file mod: ");
|
||||
out.append(wallpaperFile != null ? wallpaperFile.lastModified() : "null");
|
||||
if (connection == null) {
|
||||
out.append(", no connection");
|
||||
} else {
|
||||
out.append(", info: ");
|
||||
out.append(connection.mInfo);
|
||||
out.append(", engine(s):");
|
||||
connection.forEachDisplayConnector(connector -> {
|
||||
if (connector.mEngine != null) {
|
||||
out.append(" ");
|
||||
out.append(defaultString(connector.mEngine));
|
||||
} else {
|
||||
out.append(" null");
|
||||
}
|
||||
});
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static String defaultString(Object o) {
|
||||
return o.getClass().getSimpleName() + "@" + Integer.toHexString(o.hashCode());
|
||||
}
|
||||
|
||||
// Called during initialization of a given user's wallpaper bookkeeping
|
||||
boolean cropExists() {
|
||||
return cropFile.exists();
|
||||
|
||||
@@ -194,7 +194,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
|
||||
private final Object mLock = new Object();
|
||||
private final boolean mEnableSeparateLockScreenEngine;
|
||||
/** True to enable a second engine for lock screen wallpaper when different from system wp. */
|
||||
@VisibleForTesting
|
||||
final boolean mEnableSeparateLockScreenEngine;
|
||||
/** Tracks wallpaper being migrated from system+lock to lock when setting static wp. */
|
||||
WallpaperDestinationChangeHandler mPendingMigrationViaStatic;
|
||||
|
||||
/**
|
||||
* Minimum time between crashes of a wallpaper service for us to consider
|
||||
@@ -241,11 +245,161 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
return (wallpaper != null) ? wallpaper : mWallpaper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(int event, String path) {
|
||||
if (path == null) {
|
||||
// Handles static wallpaper changes generated by WallpaperObserver events when
|
||||
// mEnableSeparateLockScreenEngine is true.
|
||||
private void updateWallpapers(int event, String path) {
|
||||
// System and system+lock changes happen on the system wallpaper input file;
|
||||
// lock-only changes happen on the dedicated lock wallpaper input file
|
||||
final File changedFile = new File(mWallpaperDir, path);
|
||||
final boolean sysWallpaperChanged = (mWallpaperFile.equals(changedFile));
|
||||
final boolean lockWallpaperChanged = (mWallpaperLockFile.equals(changedFile));
|
||||
final WallpaperData wallpaper = dataForEvent(sysWallpaperChanged, lockWallpaperChanged);
|
||||
|
||||
final boolean moved = (event == MOVED_TO);
|
||||
final boolean written = (event == CLOSE_WRITE || moved);
|
||||
final boolean isMigration = moved && lockWallpaperChanged;
|
||||
final boolean isRestore = moved && !isMigration;
|
||||
final boolean isAppliedToLock = (wallpaper.mWhich & FLAG_LOCK) != 0;
|
||||
final boolean needsUpdate = wallpaper.wallpaperComponent == null
|
||||
|| event != CLOSE_WRITE // includes the MOVED_TO case
|
||||
|| wallpaper.imageWallpaperPending;
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Wallpaper file change: evt=" + event
|
||||
+ " path=" + path
|
||||
+ " sys=" + sysWallpaperChanged
|
||||
+ " lock=" + lockWallpaperChanged
|
||||
+ " imagePending=" + wallpaper.imageWallpaperPending
|
||||
+ " mWhich=0x" + Integer.toHexString(wallpaper.mWhich)
|
||||
+ " written=" + written
|
||||
+ " isMigration=" + isMigration
|
||||
+ " isRestore=" + isRestore
|
||||
+ " isAppliedToLock=" + isAppliedToLock
|
||||
+ " needsUpdate=" + needsUpdate);
|
||||
}
|
||||
|
||||
if (isMigration) {
|
||||
// When separate lock screen engine is supported, migration will be handled by
|
||||
// WallpaperDestinationChangeHandler.
|
||||
return;
|
||||
}
|
||||
if (!(sysWallpaperChanged || lockWallpaperChanged)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int notifyColorsWhich = 0;
|
||||
synchronized (mLock) {
|
||||
notifyCallbacksLocked(wallpaper);
|
||||
|
||||
if (!written || !needsUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Setting new static wallpaper: which=" + wallpaper.mWhich);
|
||||
}
|
||||
|
||||
WallpaperDestinationChangeHandler localSync = mPendingMigrationViaStatic;
|
||||
mPendingMigrationViaStatic = null;
|
||||
// The image source has finished writing the source image,
|
||||
// so we now produce the crop rect (in the background), and
|
||||
// only publish the new displayable (sub)image as a result
|
||||
// of that work.
|
||||
SELinux.restorecon(changedFile);
|
||||
if (isRestore) {
|
||||
// This is a restore, so generate the crop using any just-restored new
|
||||
// crop guidelines, making sure to preserve our local dimension hints.
|
||||
// We also make sure to reapply the correct SELinux label.
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Wallpaper restore; reloading metadata");
|
||||
}
|
||||
loadSettingsLocked(wallpaper.userId, true);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Wallpaper written; generating crop");
|
||||
}
|
||||
mWallpaperCropper.generateCrop(wallpaper);
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Crop done; invoking completion callback");
|
||||
}
|
||||
wallpaper.imageWallpaperPending = false;
|
||||
|
||||
if (sysWallpaperChanged) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Home screen wallpaper changed");
|
||||
}
|
||||
IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
|
||||
@Override
|
||||
public void sendResult(Bundle data) throws RemoteException {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "publish system wallpaper changed!");
|
||||
}
|
||||
if (localSync != null) {
|
||||
localSync.complete();
|
||||
}
|
||||
notifyWallpaperChanged(wallpaper);
|
||||
}
|
||||
};
|
||||
|
||||
// If this was the system wallpaper, rebind...
|
||||
bindWallpaperComponentLocked(mImageWallpaper, true, false, wallpaper,
|
||||
callback);
|
||||
notifyColorsWhich |= FLAG_SYSTEM;
|
||||
}
|
||||
|
||||
if (lockWallpaperChanged) {
|
||||
// This is lock-only, so (re)bind to the static engine.
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Lock screen wallpaper changed");
|
||||
}
|
||||
IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
|
||||
@Override
|
||||
public void sendResult(Bundle data) throws RemoteException {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "publish lock wallpaper changed!");
|
||||
}
|
||||
if (localSync != null) {
|
||||
localSync.complete();
|
||||
}
|
||||
notifyWallpaperChanged(wallpaper);
|
||||
}
|
||||
};
|
||||
|
||||
bindWallpaperComponentLocked(mImageWallpaper, true /* force */,
|
||||
false /* fromUser */, wallpaper, callback);
|
||||
notifyColorsWhich |= FLAG_LOCK;
|
||||
} else if (isAppliedToLock) {
|
||||
// This is system-plus-lock: we need to wipe the lock bookkeeping since
|
||||
// we're falling back to displaying the system wallpaper there.
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Lock screen wallpaper changed to same as home");
|
||||
}
|
||||
final WallpaperData lockedWallpaper = mLockWallpaperMap.get(
|
||||
mWallpaper.userId);
|
||||
if (lockedWallpaper != null) {
|
||||
detachWallpaperLocked(lockedWallpaper);
|
||||
}
|
||||
mLockWallpaperMap.remove(wallpaper.userId);
|
||||
notifyColorsWhich |= FLAG_LOCK;
|
||||
}
|
||||
|
||||
saveSettingsLocked(wallpaper.userId);
|
||||
// Notify the client immediately if only lockscreen wallpaper changed.
|
||||
if (lockWallpaperChanged && !sysWallpaperChanged) {
|
||||
notifyWallpaperChanged(wallpaper);
|
||||
}
|
||||
}
|
||||
|
||||
// Outside of the lock since it will synchronize itself
|
||||
if (notifyColorsWhich != 0) {
|
||||
notifyWallpaperColorsChanged(wallpaper, notifyColorsWhich);
|
||||
}
|
||||
}
|
||||
|
||||
// Handles static wallpaper changes generated by WallpaperObserver events when
|
||||
// mEnableSeparateLockScreenEngine is false.
|
||||
// TODO(b/266818039) Remove this method
|
||||
private void updateWallpapersLegacy(int event, String path) {
|
||||
final boolean moved = (event == MOVED_TO);
|
||||
final boolean written = (event == CLOSE_WRITE || moved);
|
||||
final File changedFile = new File(mWallpaperDir, path);
|
||||
@@ -268,7 +422,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
|
||||
if (moved && lockWallpaperChanged) {
|
||||
// TODO(b/253507223) Start lock screen WallpaperService
|
||||
// We just migrated sys -> lock to preserve imagery for an impending
|
||||
// new system-only wallpaper. Tell keyguard about it and make sure it
|
||||
// has the right SELinux label.
|
||||
@@ -323,8 +476,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
false, wallpaper, callback);
|
||||
notifyColorsWhich |= FLAG_SYSTEM;
|
||||
}
|
||||
// TODO(b/253507223) Start lock screen WallpaperService if only lock
|
||||
// screen wp changed
|
||||
if (lockWallpaperChanged
|
||||
|| (wallpaper.mWhich & FLAG_LOCK) != 0) {
|
||||
if (DEBUG) {
|
||||
@@ -356,6 +507,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
notifyWallpaperColorsChanged(wallpaper, notifyColorsWhich);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(int event, String path) {
|
||||
if (path == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEnableSeparateLockScreenEngine) {
|
||||
updateWallpapers(event, path);
|
||||
} else {
|
||||
updateWallpapersLegacy(event, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyWallpaperChanged(WallpaperData wallpaper) {
|
||||
@@ -382,6 +546,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
|
||||
void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) {
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "Notifying wallpaper colors changed");
|
||||
}
|
||||
if (wallpaper.connection != null) {
|
||||
wallpaper.connection.forEachDisplayConnector(connector -> {
|
||||
notifyWallpaperColorsChangedOnDisplay(wallpaper, which, connector.mDisplayId);
|
||||
@@ -807,7 +974,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
* A map for each display.
|
||||
* Use {@link #getDisplayConnectorOrCreate(int displayId)} to ensure the display is usable.
|
||||
*/
|
||||
private SparseArray<DisplayConnector> mDisplayConnector = new SparseArray<>();
|
||||
private final SparseArray<DisplayConnector> mDisplayConnector = new SparseArray<>();
|
||||
|
||||
/** Time in milliseconds until we expect the wallpaper to reconnect (unless we're in the
|
||||
* middle of an update). If exceeded, the wallpaper gets reset to the system default. */
|
||||
@@ -1170,6 +1337,110 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks wallpaper information during a wallpaper change and does bookkeeping afterwards to
|
||||
* update Engine destination, wallpaper maps, and last wallpaper.
|
||||
*/
|
||||
class WallpaperDestinationChangeHandler {
|
||||
final WallpaperData mNewWallpaper;
|
||||
final WallpaperData mOriginalSystem;
|
||||
|
||||
WallpaperDestinationChangeHandler(WallpaperData newWallpaper) {
|
||||
this.mNewWallpaper = newWallpaper;
|
||||
WallpaperData sysWp = mWallpaperMap.get(newWallpaper.userId);
|
||||
mOriginalSystem = new WallpaperData(sysWp);
|
||||
}
|
||||
|
||||
void complete() {
|
||||
// Only changes from home+lock to just home or lock need attention
|
||||
// If setting the wallpaper fails, this callback will be called
|
||||
// when the wallpaper is detached, in which case wallpapers may have
|
||||
// already changed. Make sure we're not overwriting a more recent wallpaper.
|
||||
if (mNewWallpaper.mSystemWasBoth) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Handling change from system+lock wallpaper");
|
||||
}
|
||||
if (mNewWallpaper.mWhich == FLAG_SYSTEM) {
|
||||
// New wp is system only, so old system+lock is now lock only
|
||||
final boolean originalIsStatic = mImageWallpaper.equals(
|
||||
mOriginalSystem.wallpaperComponent);
|
||||
if (originalIsStatic) {
|
||||
// Static wp: image file rename has already been tried via
|
||||
// migrateStaticSystemToLockWallpaperLocked() and added to the lock wp map
|
||||
// if successful.
|
||||
WallpaperData lockWp = mLockWallpaperMap.get(mNewWallpaper.userId);
|
||||
if (lockWp != null) {
|
||||
// Successful rename, set old system+lock to the pending lock wp
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "static system+lock to system success");
|
||||
}
|
||||
lockWp.wallpaperComponent =
|
||||
mOriginalSystem.wallpaperComponent;
|
||||
lockWp.connection = mOriginalSystem.connection;
|
||||
lockWp.connection.mWallpaper = lockWp;
|
||||
updateEngineFlags(mOriginalSystem, FLAG_LOCK);
|
||||
notifyWallpaperColorsChanged(lockWp, FLAG_LOCK);
|
||||
} else {
|
||||
// Failed rename, use current system wp for both
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "static system+lock to system failure");
|
||||
}
|
||||
WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId);
|
||||
currentSystem.mWhich = FLAG_SYSTEM | FLAG_LOCK;
|
||||
updateEngineFlags(currentSystem, FLAG_SYSTEM | FLAG_LOCK);
|
||||
mLockWallpaperMap.remove(mNewWallpaper.userId);
|
||||
}
|
||||
} else {
|
||||
// Live wp: just update old system+lock to lock only
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "live system+lock to system success");
|
||||
}
|
||||
mOriginalSystem.mWhich = FLAG_LOCK;
|
||||
updateEngineFlags(mOriginalSystem, FLAG_LOCK);
|
||||
mLockWallpaperMap.put(mNewWallpaper.userId, mOriginalSystem);
|
||||
mLastLockWallpaper = mOriginalSystem;
|
||||
notifyWallpaperColorsChanged(mOriginalSystem, FLAG_LOCK);
|
||||
}
|
||||
} else if (mNewWallpaper.mWhich == FLAG_LOCK) {
|
||||
// New wp is lock only, so old system+lock is now system only
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "system+lock to lock");
|
||||
}
|
||||
WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId);
|
||||
if (currentSystem.wallpaperId == mOriginalSystem.wallpaperId) {
|
||||
currentSystem.mWhich = FLAG_SYSTEM;
|
||||
updateEngineFlags(currentSystem, FLAG_SYSTEM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "--- wallpaper changed --");
|
||||
Slog.v(TAG, "new sysWp: " + mWallpaperMap.get(mCurrentUserId));
|
||||
Slog.v(TAG, "new lockWp: " + mLockWallpaperMap.get(mCurrentUserId));
|
||||
Slog.v(TAG, "new lastWp: " + mLastWallpaper);
|
||||
Slog.v(TAG, "new lastLockWp: " + mLastLockWallpaper);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEngineFlags(WallpaperData wallpaper, @SetWallpaperFlags int which) {
|
||||
if (wallpaper.connection == null) {
|
||||
return;
|
||||
}
|
||||
wallpaper.connection.forEachDisplayConnector(
|
||||
connector -> {
|
||||
try {
|
||||
if (connector.mEngine != null) {
|
||||
connector.mEngine.setWallpaperFlags(which);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to update wallpaper engine flags", e);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyPackageMonitor extends PackageMonitor {
|
||||
@Override
|
||||
public void onPackageUpdateFinished(String packageName, int uid) {
|
||||
@@ -1345,6 +1616,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
|
||||
mEnableSeparateLockScreenEngine = mContext.getResources().getBoolean(
|
||||
R.bool.config_independentLockscreenLiveWallpaper);
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Separate lock screen engine enabled: " + mEnableSeparateLockScreenEngine);
|
||||
}
|
||||
|
||||
LocalServices.addService(WallpaperManagerInternal.class, new LocalService());
|
||||
}
|
||||
@@ -2467,23 +2741,33 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) Slog.v(TAG, "setWallpaper which=0x" + Integer.toHexString(which));
|
||||
WallpaperData wallpaper;
|
||||
final WallpaperData originalSystemWallpaper = mWallpaperMap.get(userId);
|
||||
final boolean systemIsStatic =
|
||||
originalSystemWallpaper != null && mImageWallpaper.equals(
|
||||
originalSystemWallpaper.wallpaperComponent);
|
||||
final boolean systemIsBoth = mLockWallpaperMap.get(userId) == null;
|
||||
|
||||
/* If we're setting system but not lock, and lock is currently sharing the system
|
||||
* wallpaper, we need to migrate that image over to being lock-only before
|
||||
* the caller here writes new bitmap data.
|
||||
*/
|
||||
if (which == FLAG_SYSTEM && mLockWallpaperMap.get(userId) == null) {
|
||||
if (which == FLAG_SYSTEM && systemIsStatic && systemIsBoth) {
|
||||
Slog.i(TAG, "Migrating current wallpaper to be lock-only before"
|
||||
+ "updating system wallpaper");
|
||||
migrateSystemToLockWallpaperLocked(userId);
|
||||
+ " updating system wallpaper");
|
||||
migrateStaticSystemToLockWallpaperLocked(userId);
|
||||
}
|
||||
|
||||
wallpaper = getWallpaperSafeLocked(userId, which);
|
||||
if (mPendingMigrationViaStatic != null) {
|
||||
Slog.w(TAG, "Starting new static wp migration before previous migration finished");
|
||||
}
|
||||
mPendingMigrationViaStatic = new WallpaperDestinationChangeHandler(wallpaper);
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper, extras);
|
||||
if (pfd != null) {
|
||||
wallpaper.imageWallpaperPending = true;
|
||||
wallpaper.mSystemWasBoth = systemIsBoth;
|
||||
wallpaper.mWhich = which;
|
||||
wallpaper.setComplete = completion;
|
||||
wallpaper.fromForegroundApp = fromForegroundApp;
|
||||
@@ -2498,7 +2782,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateSystemToLockWallpaperLocked(int userId) {
|
||||
private void migrateStaticSystemToLockWallpaperLocked(int userId) {
|
||||
WallpaperData sysWP = mWallpaperMap.get(userId);
|
||||
if (sysWP == null) {
|
||||
if (DEBUG) {
|
||||
@@ -2520,14 +2804,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
try {
|
||||
Os.rename(sysWP.wallpaperFile.getAbsolutePath(), lockWP.wallpaperFile.getAbsolutePath());
|
||||
Os.rename(sysWP.cropFile.getAbsolutePath(), lockWP.cropFile.getAbsolutePath());
|
||||
mLockWallpaperMap.put(userId, lockWP);
|
||||
if (mEnableSeparateLockScreenEngine) {
|
||||
SELinux.restorecon(lockWP.wallpaperFile);
|
||||
mLastLockWallpaper = lockWP;
|
||||
}
|
||||
} catch (ErrnoException e) {
|
||||
Slog.e(TAG, "Can't migrate system wallpaper: " + e.getMessage());
|
||||
lockWP.wallpaperFile.delete();
|
||||
lockWP.cropFile.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
mLockWallpaperMap.put(userId, lockWP);
|
||||
}
|
||||
|
||||
ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper,
|
||||
@@ -2582,11 +2869,116 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
|
||||
@VisibleForTesting
|
||||
void setWallpaperComponent(ComponentName name, @SetWallpaperFlags int which, int userId) {
|
||||
if (mEnableSeparateLockScreenEngine) {
|
||||
setWallpaperComponentInternal(name, which, userId);
|
||||
} else {
|
||||
setWallpaperComponentInternalLegacy(name, which, userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void setWallpaperComponentInternal(ComponentName name, @SetWallpaperFlags int which,
|
||||
int userIdIn) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Setting new live wallpaper: which=" + which + ", component: " + name);
|
||||
}
|
||||
final int userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(),
|
||||
userIdIn, false /* all */, true /* full */, "changing live wallpaper",
|
||||
null /* pkg */);
|
||||
checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
|
||||
|
||||
boolean shouldNotifyColors = false;
|
||||
final WallpaperData newWallpaper;
|
||||
|
||||
synchronized (mLock) {
|
||||
Slog.v(TAG, "setWallpaperComponent name=" + name);
|
||||
final WallpaperData originalSystemWallpaper = mWallpaperMap.get(userId);
|
||||
if (originalSystemWallpaper == null) {
|
||||
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
|
||||
}
|
||||
final boolean systemIsStatic = mImageWallpaper.equals(
|
||||
originalSystemWallpaper.wallpaperComponent);
|
||||
final boolean systemIsBoth = mLockWallpaperMap.get(userId) == null;
|
||||
|
||||
if (which == FLAG_SYSTEM && systemIsBoth && systemIsStatic) {
|
||||
// Migrate current static system+lock wp to lock only before proceeding.
|
||||
Slog.i(TAG, "Migrating current wallpaper to be lock-only before"
|
||||
+ "updating system wallpaper");
|
||||
migrateStaticSystemToLockWallpaperLocked(userId);
|
||||
}
|
||||
|
||||
newWallpaper = getWallpaperSafeLocked(userId, which);
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
|
||||
try {
|
||||
newWallpaper.imageWallpaperPending = false;
|
||||
newWallpaper.mWhich = which;
|
||||
newWallpaper.mSystemWasBoth = systemIsBoth;
|
||||
final WallpaperDestinationChangeHandler
|
||||
liveSync = new WallpaperDestinationChangeHandler(
|
||||
newWallpaper);
|
||||
boolean same = changingToSame(name, newWallpaper);
|
||||
IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
|
||||
@Override
|
||||
public void sendResult(Bundle data) throws RemoteException {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "publish system wallpaper changed!");
|
||||
}
|
||||
liveSync.complete();
|
||||
}
|
||||
};
|
||||
boolean bindSuccess = bindWallpaperComponentLocked(name, /* force */
|
||||
false, /* fromUser */ true, newWallpaper, callback);
|
||||
if (bindSuccess) {
|
||||
if (!same) {
|
||||
newWallpaper.primaryColors = null;
|
||||
} else {
|
||||
if (newWallpaper.connection != null) {
|
||||
newWallpaper.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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
newWallpaper.wallpaperId = makeWallpaperIdLocked();
|
||||
notifyCallbacksLocked(newWallpaper);
|
||||
shouldNotifyColors = true;
|
||||
|
||||
if (which == (FLAG_SYSTEM | FLAG_LOCK)) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Lock screen wallpaper changed to same as home");
|
||||
}
|
||||
final WallpaperData lockedWallpaper = mLockWallpaperMap.get(
|
||||
newWallpaper.userId);
|
||||
if (lockedWallpaper != null) {
|
||||
detachWallpaperLocked(lockedWallpaper);
|
||||
}
|
||||
mLockWallpaperMap.remove(newWallpaper.userId);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldNotifyColors) {
|
||||
notifyWallpaperColorsChanged(newWallpaper, which);
|
||||
notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/266818039) Remove this method
|
||||
private void setWallpaperComponentInternalLegacy(ComponentName name,
|
||||
@SetWallpaperFlags int which, int userId) {
|
||||
userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
|
||||
false /* all */, true /* full */, "changing live wallpaper", null /* pkg */);
|
||||
checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
|
||||
|
||||
// TODO(b/253507223) Use passed destination and properly start lock screen LWP
|
||||
int legacyWhich = FLAG_SYSTEM;
|
||||
boolean shouldNotifyColors = false;
|
||||
WallpaperData wallpaper;
|
||||
@@ -2609,7 +3001,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
// 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);
|
||||
migrateStaticSystemToLockWallpaperLocked(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2689,8 +3081,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
if (componentName == null) {
|
||||
// Fall back to static image wallpaper
|
||||
componentName = mImageWallpaper;
|
||||
//clearWallpaperComponentLocked();
|
||||
//return;
|
||||
if (DEBUG_LIVE) Slog.v(TAG, "No default component; using image wallpaper");
|
||||
}
|
||||
}
|
||||
@@ -2713,11 +3103,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
return false;
|
||||
}
|
||||
|
||||
// This will only get set for non-static wallpapers.
|
||||
WallpaperInfo wi = null;
|
||||
|
||||
Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
|
||||
if (componentName != null && !componentName.equals(mImageWallpaper)) {
|
||||
// Make sure the selected service is actually a wallpaper service.
|
||||
// The requested component is not the static wallpaper service, so make sure it's
|
||||
// actually a wallpaper service.
|
||||
List<ResolveInfo> ris =
|
||||
mIPackageManager.queryIntentServices(intent,
|
||||
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
|
||||
@@ -2789,13 +3181,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
|
||||
com.android.internal.R.string.wallpaper_binding_label);
|
||||
intent.putExtra(Intent.EXTRA_CLIENT_INTENT, clientIntent);
|
||||
if (!mContext.bindServiceAsUser(intent, newConn,
|
||||
boolean bindSuccess = mContext.bindServiceAsUser(intent, newConn,
|
||||
Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI
|
||||
| Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
|
||||
| Context.BIND_INCLUDE_CAPABILITIES,
|
||||
new UserHandle(serviceUserId))) {
|
||||
String msg = "Unable to bind service: "
|
||||
+ componentName;
|
||||
new UserHandle(serviceUserId));
|
||||
if (!bindSuccess) {
|
||||
String msg = "Unable to bind service: " + componentName;
|
||||
if (fromUser) {
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
@@ -2834,15 +3226,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
// Updates tracking of the currently bound wallpapers. Assumes mEnableSeparateLockScreenEngine
|
||||
// is true.
|
||||
private void updateCurrentWallpapers(WallpaperData newWallpaper) {
|
||||
if (newWallpaper.userId == mCurrentUserId && !newWallpaper.equals(mFallbackWallpaper)) {
|
||||
if (newWallpaper.mWhich == (FLAG_SYSTEM | FLAG_LOCK)) {
|
||||
mLastWallpaper = newWallpaper;
|
||||
mLastLockWallpaper = null;
|
||||
} else if (newWallpaper.mWhich == FLAG_SYSTEM) {
|
||||
mLastWallpaper = newWallpaper;
|
||||
} else if (newWallpaper.mWhich == FLAG_LOCK) {
|
||||
mLastLockWallpaper = newWallpaper;
|
||||
}
|
||||
if (newWallpaper.userId != mCurrentUserId || newWallpaper.equals(mFallbackWallpaper)) {
|
||||
return;
|
||||
}
|
||||
if (newWallpaper.mWhich == (FLAG_SYSTEM | FLAG_LOCK)) {
|
||||
mLastWallpaper = newWallpaper;
|
||||
} else if (newWallpaper.mWhich == FLAG_SYSTEM) {
|
||||
mLastWallpaper = newWallpaper;
|
||||
} else if (newWallpaper.mWhich == FLAG_LOCK) {
|
||||
mLastLockWallpaper = newWallpaper;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2854,10 +3246,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
boolean homeUpdated = (newWallpaper.mWhich & FLAG_SYSTEM) != 0;
|
||||
boolean lockUpdated = (newWallpaper.mWhich & FLAG_LOCK) != 0;
|
||||
// This is the case where a home+lock wallpaper was changed to home-only, and the old
|
||||
// home+lock became (static) or will become (live) lock-only.
|
||||
boolean lockNeedsHomeWallpaper = mLastLockWallpaper == null && !lockUpdated;
|
||||
if (mLastWallpaper != null && homeUpdated && !lockNeedsHomeWallpaper) {
|
||||
boolean systemWillBecomeLock = newWallpaper.mSystemWasBoth && !lockUpdated;
|
||||
if (mLastWallpaper != null && homeUpdated && !systemWillBecomeLock) {
|
||||
detachWallpaperLocked(mLastWallpaper);
|
||||
}
|
||||
if (mLastLockWallpaper != null && lockUpdated) {
|
||||
@@ -2865,8 +3255,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
// Frees up all rendering resources used by the given wallpaper so that the WallpaperData object
|
||||
// can be reused: detaches Engine, unbinds WallpaperService, etc.
|
||||
private void detachWallpaperLocked(WallpaperData wallpaper) {
|
||||
if (wallpaper.connection != null) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Detaching wallpaper: " + wallpaper);
|
||||
}
|
||||
if (wallpaper.connection.mReply != null) {
|
||||
try {
|
||||
wallpaper.connection.mReply.sendResult(null);
|
||||
@@ -2882,7 +3277,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed detaching wallpaper service ", e);
|
||||
}
|
||||
mContext.unbindService(wallpaper.connection);
|
||||
try {
|
||||
mContext.unbindService(wallpaper.connection);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Slog.w(TAG, "Attempted to unbind unregistered service");
|
||||
}
|
||||
wallpaper.connection.forEachDisplayConnector(DisplayConnector::disconnectLocked);
|
||||
wallpaper.connection.mService = null;
|
||||
wallpaper.connection.mDisplayConnector.clear();
|
||||
@@ -3192,6 +3591,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines and returns the current wallpaper for the given user and destination, creating
|
||||
* a valid entry if it does not already exist and adding it to the appropriate wallpaper map.
|
||||
*
|
||||
* Sometimes it is expected the wallpaper map may not have a user's data. E.g. This could
|
||||
* happen during user switch. The async user switch observer may not have received
|
||||
* the event yet. We use this safe method when we don't care about this ordering and just
|
||||
@@ -3215,10 +3617,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
// unified lock, so we bring up the saved state lazily now and recheck.
|
||||
loadSettingsLocked(userId, false);
|
||||
wallpaper = whichSet.get(userId);
|
||||
// if it's still null here, this is a lock-only operation and there is not
|
||||
// yet a lock-only wallpaper set for this user, so we need to establish
|
||||
// it now.
|
||||
if (wallpaper == null) {
|
||||
// if it's still null here, this is likely a lock-only operation and there is not
|
||||
// currently a lock-only wallpaper set for this user, so we need to establish
|
||||
// it now.
|
||||
if (which == FLAG_LOCK) {
|
||||
wallpaper = new WallpaperData(userId, FLAG_LOCK);
|
||||
mLockWallpaperMap.put(userId, wallpaper);
|
||||
@@ -3341,6 +3743,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
WallpaperData lockWallpaper = mLockWallpaperMap.get(userId);
|
||||
if (lockWallpaper != null) {
|
||||
ensureSaneWallpaperData(lockWallpaper);
|
||||
lockWallpaper.mWhich = FLAG_LOCK;
|
||||
wallpaper.mWhich = FLAG_SYSTEM;
|
||||
} else {
|
||||
wallpaper.mWhich = FLAG_SYSTEM | FLAG_LOCK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user