summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/IWallpaperManager.aidl11
-rw-r--r--core/java/android/app/WallpaperManager.java20
-rw-r--r--core/java/android/service/wallpaper/IWallpaperConnection.aidl2
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java4
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java178
5 files changed, 155 insertions, 60 deletions
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 3a2038d40952..666f7218a4f2 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -142,19 +142,20 @@ interface IWallpaperManager {
*
* @param which either {@link WallpaperManager#FLAG_LOCK}
* or {@link WallpaperManager#FLAG_SYSTEM}
+ * @param displayId Which display is interested
* @return colors of chosen wallpaper
*/
- WallpaperColors getWallpaperColors(int which, int userId);
+ WallpaperColors getWallpaperColors(int which, int userId, int displayId);
/**
- * Register a callback to receive color updates
+ * Register a callback to receive color updates from a display
*/
- void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
+ void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId, int displayId);
/**
- * Unregister a callback that was receiving color updates
+ * Unregister a callback that was receiving color updates from a display
*/
- void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
+ void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId, int displayId);
/**
* Called from SystemUI when it shows the AoD UI.
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 27ae0b0314d0..a929fe0f688e 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -307,13 +307,14 @@ public class WallpaperManager {
* @param callback Listener
* @param handler Thread to call it from. Main thread if null.
* @param userId Owner of the wallpaper or UserHandle.USER_ALL
+ * @param displayId Caller comes from which display
*/
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
- @Nullable Handler handler, int userId) {
+ @Nullable Handler handler, int userId, int displayId) {
synchronized (this) {
if (!mColorCallbackRegistered) {
try {
- mService.registerWallpaperColorsCallback(this, userId);
+ mService.registerWallpaperColorsCallback(this, userId, displayId);
mColorCallbackRegistered = true;
} catch (RemoteException e) {
// Failed, service is gone
@@ -329,16 +330,17 @@ public class WallpaperManager {
*
* @param callback listener
* @param userId Owner of the wallpaper or UserHandle.USER_ALL
+ * @param displayId Which display is interested
*/
public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
- int userId) {
+ int userId, int displayId) {
synchronized (this) {
mColorListeners.removeIf(pair -> pair.first == callback);
if (mColorListeners.size() == 0 && mColorCallbackRegistered) {
mColorCallbackRegistered = false;
try {
- mService.unregisterWallpaperColorsCallback(this, userId);
+ mService.unregisterWallpaperColorsCallback(this, userId, displayId);
} catch (RemoteException e) {
// Failed, service is gone
Log.w(TAG, "Can't unregister color updates", e);
@@ -370,14 +372,14 @@ public class WallpaperManager {
}
}
- WallpaperColors getWallpaperColors(int which, int userId) {
+ WallpaperColors getWallpaperColors(int which, int userId, int displayId) {
if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
throw new IllegalArgumentException(
"Must request colors for exactly one kind of wallpaper");
}
try {
- return mService.getWallpaperColors(which, userId);
+ return mService.getWallpaperColors(which, userId, displayId);
} catch (RemoteException e) {
// Can't get colors, connection lost.
}
@@ -894,7 +896,7 @@ public class WallpaperManager {
@UnsupportedAppUsage
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
@NonNull Handler handler, int userId) {
- sGlobals.addOnColorsChangedListener(listener, handler, userId);
+ sGlobals.addOnColorsChangedListener(listener, handler, userId, mContext.getDisplayId());
}
/**
@@ -913,7 +915,7 @@ public class WallpaperManager {
*/
public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
int userId) {
- sGlobals.removeOnColorsChangedListener(callback, userId);
+ sGlobals.removeOnColorsChangedListener(callback, userId, mContext.getDisplayId());
}
/**
@@ -947,7 +949,7 @@ public class WallpaperManager {
*/
@UnsupportedAppUsage
public @Nullable WallpaperColors getWallpaperColors(int which, int userId) {
- return sGlobals.getWallpaperColors(which, userId);
+ return sGlobals.getWallpaperColors(which, userId, mContext.getDisplayId());
}
/**
diff --git a/core/java/android/service/wallpaper/IWallpaperConnection.aidl b/core/java/android/service/wallpaper/IWallpaperConnection.aidl
index a976d0e40423..f334d9d3e874 100644
--- a/core/java/android/service/wallpaper/IWallpaperConnection.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperConnection.aidl
@@ -27,5 +27,5 @@ interface IWallpaperConnection {
void attachEngine(IWallpaperEngine engine, int displayId);
void engineShown(IWallpaperEngine engine);
ParcelFileDescriptor setWallpaper(String name);
- void onWallpaperColorsChanged(in WallpaperColors colors);
+ void onWallpaperColorsChanged(in WallpaperColors colors, int displayId);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 9079502fa6b2..984846e33b1d 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -645,7 +645,7 @@ public abstract class WallpaperService extends Service {
try {
final WallpaperColors newColors = onComputeColors();
if (mConnection != null) {
- mConnection.onWallpaperColorsChanged(newColors);
+ mConnection.onWallpaperColorsChanged(newColors, mDisplay.getDisplayId());
} else {
Log.w(TAG, "Can't notify system because wallpaper connection "
+ "was not established.");
@@ -1473,7 +1473,7 @@ public abstract class WallpaperService extends Service {
break;
}
try {
- mConnection.onWallpaperColorsChanged(mEngine.onComputeColors());
+ mConnection.onWallpaperColorsChanged(mEngine.onComputeColors(), mDisplayId);
} catch (RemoteException e) {
// Connection went away, nothing to do in here.
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index f00877030145..01bff07d1bb0 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -350,12 +350,34 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
private void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) {
+ if (wallpaper.connection != null) {
+ wallpaper.connection.forEachDisplayConnector(connector -> {
+ notifyWallpaperColorsChangedOnDisplay(wallpaper, which, connector.mDisplayId);
+ });
+ } else { // Lock wallpaper does not have WallpaperConnection.
+ notifyWallpaperColorsChangedOnDisplay(wallpaper, which, DEFAULT_DISPLAY);
+ }
+ }
+
+ private RemoteCallbackList<IWallpaperManagerCallback> getWallpaperCallbacks(int userId,
+ int displayId) {
+ RemoteCallbackList<IWallpaperManagerCallback> listeners = null;
+ final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> displayListeners =
+ mColorsChangedListeners.get(userId);
+ if (displayListeners != null) {
+ listeners = displayListeners.get(displayId);
+ }
+ return listeners;
+ }
+
+ private void notifyWallpaperColorsChangedOnDisplay(@NonNull WallpaperData wallpaper, int which,
+ int displayId) {
boolean needsExtraction;
synchronized (mLock) {
final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
- mColorsChangedListeners.get(wallpaper.userId);
+ getWallpaperCallbacks(wallpaper.userId, displayId);
final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
- mColorsChangedListeners.get(UserHandle.USER_ALL);
+ getWallpaperCallbacks(UserHandle.USER_ALL, displayId);
// No-op until someone is listening to it.
if (emptyCallbackList(currentUserColorListeners) &&
emptyCallbackList(userAllColorListeners)) {
@@ -363,7 +385,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
if (DEBUG) {
- Slog.v(TAG, "notifyWallpaperColorsChanged " + which);
+ Slog.v(TAG, "notifyWallpaperColorsChangedOnDisplay " + which);
}
needsExtraction = wallpaper.primaryColors == null;
@@ -371,7 +393,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// Let's notify the current values, it's fine if it's null, it just means
// that we don't know yet.
- notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
+ notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId);
if (needsExtraction) {
extractColors(wallpaper);
@@ -381,7 +403,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
return;
}
}
- notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
+ notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId);
}
}
@@ -390,14 +412,14 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
private void notifyColorListeners(@NonNull WallpaperColors wallpaperColors, int which,
- int userId) {
+ int userId, int displayId) {
final IWallpaperManagerCallback keyguardListener;
final ArrayList<IWallpaperManagerCallback> colorListeners = new ArrayList<>();
synchronized (mLock) {
final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
- mColorsChangedListeners.get(userId);
+ getWallpaperCallbacks(userId, displayId);
final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
- mColorsChangedListeners.get(UserHandle.USER_ALL);
+ getWallpaperCallbacks(UserHandle.USER_ALL, displayId);
keyguardListener = mKeyguardListener;
if (currentUserColorListeners != null) {
@@ -427,7 +449,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
- if (keyguardListener != null) {
+ // Only shows Keyguard on default display
+ if (keyguardListener != null && displayId == DEFAULT_DISPLAY) {
try {
keyguardListener.onWallpaperColorsChanged(wallpaperColors, which, userId);
} catch (RemoteException e) {
@@ -446,6 +469,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
String cropFile = null;
int wallpaperId;
+ if (wallpaper.equals(mFallbackWallpaper)) {
+ extractDefaultImageWallpaperColors();
+ return;
+ }
+
synchronized (mLock) {
// Not having a wallpaperComponent means it's a lock screen wallpaper.
final boolean imageWallpaper = mImageWallpaper.equals(wallpaper.wallpaperComponent)
@@ -482,6 +510,39 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
+ private void extractDefaultImageWallpaperColors() {
+ synchronized (mLock) {
+ if (mFallbackWallpaper.primaryColors != null) return;
+ }
+
+ if (DEBUG) Slog.d(TAG, "Extract default image wallpaper colors");
+ WallpaperColors colors = null;
+ final InputStream is = WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM);
+ if (is != null) {
+ try {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
+ if (bitmap != null) {
+ colors = WallpaperColors.fromBitmap(bitmap);
+ bitmap.recycle();
+ }
+ } catch (OutOfMemoryError e) {
+ Slog.w(TAG, "Can't decode default wallpaper stream", e);
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+ }
+
+ if (colors == null) {
+ Slog.e(TAG, "Extract default image wallpaper colors failed");
+ return;
+ }
+
+ synchronized (mLock) {
+ mFallbackWallpaper.primaryColors = colors;
+ }
+ }
+
/**
* Once a new wallpaper has been written via setWallpaper(...), it needs to be cropped
* for display.
@@ -696,6 +757,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
targetWallpaper.connection.removeDisplayConnector(displayId);
removeDisplayData(displayId);
}
+ for (int i = mColorsChangedListeners.size() - 1; i >= 0; i--) {
+ final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> callbacks =
+ mColorsChangedListeners.valueAt(i);
+ callbacks.delete(displayId);
+ }
}
}
@@ -706,9 +772,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
/**
* Map of color listeners per user id.
- * The key will be the id of a user or UserHandle.USER_ALL - for wildcard listeners.
+ * The first key will be the id of a user or UserHandle.USER_ALL - for wildcard listeners.
+ * The secondary key will be the display id, which means which display the listener is
+ * interested in.
*/
- private final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>>
+ private final SparseArray<SparseArray<RemoteCallbackList<IWallpaperManagerCallback>>>
mColorsChangedListeners;
private WallpaperData mLastWallpaper;
private IWallpaperManagerCallback mKeyguardListener;
@@ -1228,9 +1296,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
/**
* Called by a live wallpaper if its colors have changed.
* @param primaryColors representation of wallpaper primary colors
+ * @param displayId for which display
*/
@Override
- public void onWallpaperColorsChanged(WallpaperColors primaryColors) {
+ public void onWallpaperColorsChanged(WallpaperColors primaryColors, int displayId) {
int which;
synchronized (mLock) {
// Do not broadcast changes on ImageWallpaper since it's handled
@@ -1243,14 +1312,16 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// Live wallpapers always are system wallpapers.
which = FLAG_SYSTEM;
- // It's also the lock screen wallpaper when we don't have a bitmap in there
- WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId);
- if (lockedWallpaper == null) {
- which |= FLAG_LOCK;
+ // It's also the lock screen wallpaper when we don't have a bitmap in there.
+ if (displayId == DEFAULT_DISPLAY) {
+ final WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId);
+ if (lockedWallpaper == null) {
+ which |= FLAG_LOCK;
+ }
}
}
if (which != 0) {
- notifyWallpaperColorsChanged(mWallpaper, which);
+ notifyWallpaperColorsChangedOnDisplay(mWallpaper, which, displayId);
}
}
@@ -1277,16 +1348,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
Slog.w(TAG, "Failed to set ambient mode state", e);
}
}
- // TODO(multi-display) So far, we have shared the same wallpaper on each display.
- // Once we have multiple wallpapers on multiple displays, please complete here.
- if (displayId == DEFAULT_DISPLAY) {
- try {
- // This will trigger onComputeColors in the wallpaper engine.
- // It's fine to be locked in here since the binder is oneway.
- connector.mEngine.requestWallpaperColors();
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to request wallpaper colors", e);
- }
+ try {
+ // This will trigger onComputeColors in the wallpaper engine.
+ // It's fine to be locked in here since the binder is oneway.
+ connector.mEngine.requestWallpaperColors();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to request wallpaper colors", e);
}
}
}
@@ -1681,6 +1748,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
FgThread.getHandler().post(() -> {
notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
+ notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
});
}
@@ -1743,6 +1811,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// When clearing a wallpaper, broadcast new valid colors
if (data != null) {
notifyWallpaperColorsChanged(data, which);
+ notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
}
}
@@ -2084,35 +2153,47 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
@Override
- public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+ public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId,
+ int displayId) {
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, true, true, "registerWallpaperColorsCallback", null);
synchronized (mLock) {
- RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
- mColorsChangedListeners.get(userId);
- if (userColorsChangedListeners == null) {
- userColorsChangedListeners = new RemoteCallbackList<>();
- mColorsChangedListeners.put(userId, userColorsChangedListeners);
+ SparseArray<RemoteCallbackList<IWallpaperManagerCallback>>
+ userDisplayColorsChangedListeners = mColorsChangedListeners.get(userId);
+ if (userDisplayColorsChangedListeners == null) {
+ userDisplayColorsChangedListeners = new SparseArray<>();
+ mColorsChangedListeners.put(userId, userDisplayColorsChangedListeners);
+ }
+ RemoteCallbackList<IWallpaperManagerCallback> displayChangedListeners =
+ userDisplayColorsChangedListeners.get(displayId);
+ if (displayChangedListeners == null) {
+ displayChangedListeners = new RemoteCallbackList<>();
+ userDisplayColorsChangedListeners.put(displayId, displayChangedListeners);
}
- userColorsChangedListeners.register(cb);
+ displayChangedListeners.register(cb);
}
}
@Override
- public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+ public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId,
+ int displayId) {
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, true, true, "unregisterWallpaperColorsCallback", null);
synchronized (mLock) {
- final RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
- mColorsChangedListeners.get(userId);
- if (userColorsChangedListeners != null) {
- userColorsChangedListeners.unregister(cb);
+ SparseArray<RemoteCallbackList<IWallpaperManagerCallback>>
+ userDisplayColorsChangedListeners = mColorsChangedListeners.get(userId);
+ if (userDisplayColorsChangedListeners != null) {
+ RemoteCallbackList<IWallpaperManagerCallback> displayChangedListeners =
+ userDisplayColorsChangedListeners.get(displayId);
+ if (displayChangedListeners != null) {
+ displayChangedListeners.unregister(cb);
+ }
}
}
}
/**
- * TODO(b/115486823) Extends this method with specific display.
+ * TODO(multi-display) Extends this method with specific display.
* Propagate ambient state to wallpaper engine.
*
* @param inAmbientMode {@code true} when in ambient mode, {@code false} otherwise.
@@ -2125,7 +2206,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
if (data != null && data.connection != null && data.connection.mInfo != null
&& data.connection.mInfo.supportsAmbientMode()) {
- // TODO(b/115486823) Extends this method with specific display.
+ // TODO(multi-display) Extends this method with specific display.
engine = data.connection.getDisplayConnectorOrCreate(DEFAULT_DISPLAY).mEngine;
} else {
engine = null;
@@ -2151,7 +2232,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
@Override
- public WallpaperColors getWallpaperColors(int which, int userId) throws RemoteException {
+ public WallpaperColors getWallpaperColors(int which, int userId, int displayId)
+ throws RemoteException {
if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM");
}
@@ -2169,7 +2251,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// Try to get the system wallpaper anyway since it might
// also be the lock screen wallpaper
if (wallpaperData == null) {
- wallpaperData = mWallpaperMap.get(userId);
+ wallpaperData = findWallpaperAtDisplay(userId, displayId);
}
if (wallpaperData == null) {
@@ -2187,6 +2269,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
+ private WallpaperData findWallpaperAtDisplay(int userId, int displayId) {
+ if (mFallbackWallpaper != null && mFallbackWallpaper.connection != null
+ && mFallbackWallpaper.connection.containsDisplay(displayId)) {
+ return mFallbackWallpaper;
+ } else {
+ return mWallpaperMap.get(userId);
+ }
+ }
+
@Override
public ParcelFileDescriptor setWallpaper(String name, String callingPackage,
Rect cropHint, boolean allowBackup, Bundle extras, int which,
@@ -2382,6 +2473,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (shouldNotifyColors) {
notifyWallpaperColorsChanged(wallpaper, which);
+ notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
}
}