Merge "Multi-user and WallpaperColors" into oc-mr1-dev

This commit is contained in:
Lucas Dupin
2017-08-03 16:23:41 +00:00
committed by Android (Google) Code Review
10 changed files with 252 additions and 81 deletions

View File

@@ -144,15 +144,15 @@ interface IWallpaperManager {
* or {@link WallpaperManager#FLAG_SYSTEM} * or {@link WallpaperManager#FLAG_SYSTEM}
* @return colors of chosen wallpaper * @return colors of chosen wallpaper
*/ */
WallpaperColors getWallpaperColors(int which); WallpaperColors getWallpaperColors(int which, int userId);
/** /**
* Register a callback to receive color updates * Register a callback to receive color updates
*/ */
void registerWallpaperColorsCallback(IWallpaperManagerCallback cb); void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
/** /**
* Unregister a callback that was receiving color updates * Unregister a callback that was receiving color updates
*/ */
void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb); void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
} }

View File

@@ -34,6 +34,6 @@ oneway interface IWallpaperManagerCallback {
/** /**
* Called when wallpaper colors change * Called when wallpaper colors change
*/ */
void onWallpaperColorsChanged(in WallpaperColors colors, int which); void onWallpaperColorsChanged(in WallpaperColors colors, int which, int userId);
} }

View File

@@ -408,4 +408,13 @@ public final class WallpaperColors implements Parcelable {
return new Size(newWidth, newHeight); return new Size(newWidth, newHeight);
} }
@Override
public String toString() {
final StringBuilder colors = new StringBuilder();
for (int i = 0; i < mMainColors.size(); i++) {
colors.append(Integer.toHexString(mMainColors.get(i).toArgb())).append(" ");
}
return "[WallpaperColors: " + colors.toString() + "h: " + mColorHints + "]";
}
} }

View File

@@ -307,13 +307,14 @@ public class WallpaperManager {
* changes its colors. * changes its colors.
* @param callback Listener * @param callback Listener
* @param handler Thread to call it from. Main thread if null. * @param handler Thread to call it from. Main thread if null.
* @param userId Owner of the wallpaper or UserHandle.USER_ALL
*/ */
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener callback, public void addOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
@Nullable Handler handler) { @Nullable Handler handler, int userId) {
synchronized (this) { synchronized (this) {
if (!mColorCallbackRegistered) { if (!mColorCallbackRegistered) {
try { try {
mService.registerWallpaperColorsCallback(this); mService.registerWallpaperColorsCallback(this, userId);
mColorCallbackRegistered = true; mColorCallbackRegistered = true;
} catch (RemoteException e) { } catch (RemoteException e) {
// Failed, service is gone // Failed, service is gone
@@ -328,15 +329,17 @@ public class WallpaperManager {
* Stop listening to wallpaper color events. * Stop listening to wallpaper color events.
* *
* @param callback listener * @param callback listener
* @param userId Owner of the wallpaper or UserHandle.USER_ALL
*/ */
public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) { public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
int userId) {
synchronized (this) { synchronized (this) {
mColorListeners.removeIf(pair -> pair.first == callback); mColorListeners.removeIf(pair -> pair.first == callback);
if (mColorListeners.size() == 0 && mColorCallbackRegistered) { if (mColorListeners.size() == 0 && mColorCallbackRegistered) {
mColorCallbackRegistered = false; mColorCallbackRegistered = false;
try { try {
mService.unregisterWallpaperColorsCallback(this); mService.unregisterWallpaperColorsCallback(this, userId);
} catch (RemoteException e) { } catch (RemoteException e) {
// Failed, service is gone // Failed, service is gone
Log.w(TAG, "Can't unregister color updates", e); Log.w(TAG, "Can't unregister color updates", e);
@@ -346,7 +349,7 @@ public class WallpaperManager {
} }
@Override @Override
public void onWallpaperColorsChanged(WallpaperColors colors, int which) { public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
synchronized (this) { synchronized (this) {
for (Pair<OnColorsChangedListener, Handler> listener : mColorListeners) { for (Pair<OnColorsChangedListener, Handler> listener : mColorListeners) {
Handler handler = listener.second; Handler handler = listener.second;
@@ -361,21 +364,21 @@ public class WallpaperManager {
stillExists = mColorListeners.contains(listener); stillExists = mColorListeners.contains(listener);
} }
if (stillExists) { if (stillExists) {
listener.first.onColorsChanged(colors, which); listener.first.onColorsChanged(colors, which, userId);
} }
}); });
} }
} }
} }
WallpaperColors getWallpaperColors(int which) { WallpaperColors getWallpaperColors(int which, int userId) {
if (which != FLAG_LOCK && which != FLAG_SYSTEM) { if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Must request colors for exactly one kind of wallpaper"); "Must request colors for exactly one kind of wallpaper");
} }
try { try {
return mService.getWallpaperColors(which); return mService.getWallpaperColors(which, userId);
} catch (RemoteException e) { } catch (RemoteException e) {
// Can't get colors, connection lost. // Can't get colors, connection lost.
} }
@@ -857,7 +860,7 @@ public class WallpaperManager {
* @param listener A listener to register * @param listener A listener to register
*/ */
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) { public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
sGlobals.addOnColorsChangedListener(listener, null); addOnColorsChangedListener(listener, null);
} }
/** /**
@@ -868,25 +871,61 @@ public class WallpaperManager {
*/ */
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener, public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
@NonNull Handler handler) { @NonNull Handler handler) {
sGlobals.addOnColorsChangedListener(listener, handler); addOnColorsChangedListener(listener, handler, mContext.getUserId());
}
/**
* Registers a listener to get notified when the wallpaper colors change
* @param listener A listener to register
* @param handler Where to call it from. Will be called from the main thread
* if null.
* @param userId Owner of the wallpaper or UserHandle.USER_ALL.
* @hide
*/
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
@NonNull Handler handler, int userId) {
sGlobals.addOnColorsChangedListener(listener, handler, userId);
} }
/** /**
* Stop listening to color updates. * Stop listening to color updates.
* @param callback A callback to unsubscribe * @param callback A callback to unsubscribe.
*/ */
public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) { public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) {
sGlobals.removeOnColorsChangedListener(callback); removeOnColorsChangedListener(callback, mContext.getUserId());
}
/**
* Stop listening to color updates.
* @param callback A callback to unsubscribe.
* @param userId Owner of the wallpaper or UserHandle.USER_ALL.
* @hide
*/
public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
int userId) {
sGlobals.removeOnColorsChangedListener(callback, userId);
} }
/** /**
* Get the primary colors of a wallpaper * Get the primary colors of a wallpaper
* @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
* {@link #FLAG_LOCK} * {@link #FLAG_LOCK}
* @return a list of colors ordered by priority * @return {@link WallpaperColors} or null if colors are unknown.
*/ */
public @Nullable WallpaperColors getWallpaperColors(int which) { public @Nullable WallpaperColors getWallpaperColors(int which) {
return sGlobals.getWallpaperColors(which); return getWallpaperColors(which, mContext.getUserId());
}
/**
* Get the primary colors of a wallpaper
* @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
* {@link #FLAG_LOCK}
* @param userId Owner of the wallpaper.
* @return {@link WallpaperColors} or null if colors are unknown.
* @hide
*/
public @Nullable WallpaperColors getWallpaperColors(int which, int userId) {
return sGlobals.getWallpaperColors(which, userId);
} }
/** /**
@@ -1902,9 +1941,9 @@ public class WallpaperManager {
} }
@Override @Override
public void onWallpaperColorsChanged(WallpaperColors colors, int which) public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId)
throws RemoteException { throws RemoteException {
sGlobals.onWallpaperColorsChanged(colors, which); sGlobals.onWallpaperColorsChanged(colors, which, userId);
} }
} }
@@ -1921,5 +1960,19 @@ public class WallpaperManager {
* @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM} * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
*/ */
void onColorsChanged(WallpaperColors colors, int which); void onColorsChanged(WallpaperColors colors, int which);
/**
* Called when colors change.
* A {@link android.app.WallpaperColors} object containing a simplified
* color histogram will be given.
*
* @param colors Wallpaper color info
* @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
* @param userId Owner of the wallpaper
* @hide
*/
default void onColorsChanged(WallpaperColors colors, int which, int userId) {
onColorsChanged(colors, which);
}
} }
} }

View File

@@ -30,5 +30,6 @@ oneway interface IWallpaperEngine {
void dispatchPointer(in MotionEvent event); void dispatchPointer(in MotionEvent event);
void dispatchWallpaperCommand(String action, int x, int y, void dispatchWallpaperCommand(String action, int x, int y,
int z, in Bundle extras); int z, in Bundle extras);
void requestWallpaperColors();
void destroy(); void destroy();
} }

View File

@@ -105,6 +105,7 @@ public abstract class WallpaperService extends Service {
private static final int MSG_WINDOW_RESIZED = 10030; private static final int MSG_WINDOW_RESIZED = 10030;
private static final int MSG_WINDOW_MOVED = 10035; private static final int MSG_WINDOW_MOVED = 10035;
private static final int MSG_TOUCH_EVENT = 10040; private static final int MSG_TOUCH_EVENT = 10040;
private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
private final ArrayList<Engine> mActiveEngines private final ArrayList<Engine> mActiveEngines
= new ArrayList<Engine>(); = new ArrayList<Engine>();
@@ -626,8 +627,7 @@ public abstract class WallpaperService extends Service {
} }
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event); Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
mCaller.sendMessage(msg); mCaller.sendMessage(msg);
} else { } else {event.recycle();
event.recycle();
} }
} }
@@ -1192,6 +1192,11 @@ public abstract class WallpaperService extends Service {
} }
} }
public void requestWallpaperColors() {
Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS);
mCaller.sendMessage(msg);
}
public void destroy() { public void destroy() {
Message msg = mCaller.obtainMessage(DO_DETACH); Message msg = mCaller.obtainMessage(DO_DETACH);
mCaller.sendMessage(msg); mCaller.sendMessage(msg);
@@ -1210,7 +1215,6 @@ public abstract class WallpaperService extends Service {
mEngine = engine; mEngine = engine;
mActiveEngines.add(engine); mActiveEngines.add(engine);
engine.attach(this); engine.attach(this);
engine.notifyColorsChanged();
return; return;
} }
case DO_DETACH: { case DO_DETACH: {
@@ -1268,6 +1272,16 @@ public abstract class WallpaperService extends Service {
} }
ev.recycle(); ev.recycle();
} break; } break;
case MSG_REQUEST_WALLPAPER_COLORS: {
if (mConnection == null) {
break;
}
try {
mConnection.onWallpaperColorsChanged(mEngine.onComputeColors());
} catch (RemoteException e) {
// Connection went away, nothing to do in here.
}
} break;
default : default :
Log.w(TAG, "Unknown message type " + message.what); Log.w(TAG, "Unknown message type " + message.what);
} }

View File

@@ -22,6 +22,7 @@ import android.app.WallpaperColors;
import android.app.WallpaperManager; import android.app.WallpaperManager;
import android.content.Context; import android.content.Context;
import android.os.Trace; import android.os.Trace;
import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
@@ -44,6 +45,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
private static final int[] sGradientTypes = new int[]{TYPE_NORMAL, TYPE_DARK, TYPE_EXTRA_DARK}; private static final int[] sGradientTypes = new int[]{TYPE_NORMAL, TYPE_DARK, TYPE_EXTRA_DARK};
private static final String TAG = "ColorExtractor"; private static final String TAG = "ColorExtractor";
private static final boolean DEBUG = false;
protected final SparseArray<GradientColors[]> mGradientColors; protected final SparseArray<GradientColors[]> mGradientColors;
private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners; private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners;
@@ -147,6 +149,9 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
@Override @Override
public void onColorsChanged(WallpaperColors colors, int which) { public void onColorsChanged(WallpaperColors colors, int which) {
if (DEBUG) {
Log.d(TAG, "New wallpaper colors for " + which + ": " + colors);
}
boolean changed = false; boolean changed = false;
if ((which & WallpaperManager.FLAG_LOCK) != 0) { if ((which & WallpaperManager.FLAG_LOCK) != 0) {
mLockColors = colors; mLockColors = colors;

View File

@@ -21,6 +21,8 @@ import android.app.WallpaperManager;
import android.content.Context; import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.IWallpaperVisibilityListener; import android.view.IWallpaperVisibilityListener;
@@ -31,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.ExtractionType;
import com.android.internal.colorextraction.types.Tonal; import com.android.internal.colorextraction.types.Tonal;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@@ -75,6 +78,14 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
Log.w(TAG, "Can't listen to wallpaper visibility changes", e); Log.w(TAG, "Can't listen to wallpaper visibility changes", e);
} }
} }
WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
if (wallpaperManager != null) {
// Listen to all users instead of only the current one.
wallpaperManager.removeOnColorsChangedListener(this);
wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
UserHandle.USER_ALL);
}
} }
private void updateDefaultGradients(WallpaperColors colors) { private void updateDefaultGradients(WallpaperColors colors) {
@@ -82,7 +93,12 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
} }
@Override @Override
public void onColorsChanged(WallpaperColors colors, int which) { public void onColorsChanged(WallpaperColors colors, int which, int userId) {
if (userId != KeyguardUpdateMonitor.getCurrentUser()) {
// Colors do not belong to current user, ignoring.
return;
}
super.onColorsChanged(colors, which); super.onColorsChanged(colors, which);
if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {

View File

@@ -158,7 +158,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen
} }
@Override @Override
public void onWallpaperColorsChanged(WallpaperColors colors, int which) { public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
} }

View File

@@ -25,6 +25,7 @@ import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import android.annotation.NonNull;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.AppGlobals; import android.app.AppGlobals;
import android.app.AppOpsManager; import android.app.AppOpsManager;
@@ -63,6 +64,7 @@ import android.os.FileObserver;
import android.os.FileUtils; import android.os.FileUtils;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.IInterface;
import android.os.IRemoteCallback; import android.os.IRemoteCallback;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Process; import android.os.Process;
@@ -331,11 +333,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
} }
} }
private void notifyWallpaperColorsChanged(WallpaperData wallpaper, int which) { private void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) {
boolean needsExtraction; boolean needsExtraction;
synchronized (mLock) { synchronized (mLock) {
if (mColorsChangedListeners.getRegisteredCallbackCount() == 0) final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
mColorsChangedListeners.get(wallpaper.userId);
final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
mColorsChangedListeners.get(UserHandle.USER_ALL);
// No-op until someone is listening to it.
if (emptyCallbackList(currentUserColorListeners) &&
emptyCallbackList(userAllColorListeners)) {
return; return;
}
if (DEBUG) { if (DEBUG) {
Slog.v(TAG, "notifyWallpaperColorsChanged " + which); Slog.v(TAG, "notifyWallpaperColorsChanged " + which);
@@ -346,40 +355,66 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
// Let's notify the current values, it's fine if it's null, it just means // Let's notify the current values, it's fine if it's null, it just means
// that we don't know yet. // that we don't know yet.
notifyColorListeners(wallpaper.primaryColors, which); notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
if (needsExtraction) { if (needsExtraction) {
extractColors(wallpaper); extractColors(wallpaper);
notifyColorListeners(wallpaper.primaryColors, which); synchronized (mLock) {
// Don't need to notify if nothing changed.
if (wallpaper.primaryColors == null) {
return;
}
}
notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
} }
} }
private void notifyColorListeners(WallpaperColors wallpaperColors, int which) { private static <T extends IInterface> boolean emptyCallbackList(RemoteCallbackList<T> list) {
final IWallpaperManagerCallback[] listeners; return (list == null || list.getRegisteredCallbackCount() == 0);
}
private void notifyColorListeners(@NonNull WallpaperColors wallpaperColors, int which,
int userId) {
final IWallpaperManagerCallback keyguardListener; final IWallpaperManagerCallback keyguardListener;
final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners;
final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners;
synchronized (mLock) { synchronized (mLock) {
// Make a synchronized copy of the listeners to avoid concurrent list modification. currentUserColorListeners = mColorsChangedListeners.get(userId);
int callbackCount = mColorsChangedListeners.beginBroadcast(); userAllColorListeners = mColorsChangedListeners.get(UserHandle.USER_ALL);
listeners = new IWallpaperManagerCallback[callbackCount];
for (int i = 0; i < callbackCount; i++) {
listeners[i] = mColorsChangedListeners.getBroadcastItem(i);
}
mColorsChangedListeners.finishBroadcast();
keyguardListener = mKeyguardListener; keyguardListener = mKeyguardListener;
} }
for (int i = 0; i < listeners.length; i++) { if (currentUserColorListeners != null) {
try { int count = currentUserColorListeners.beginBroadcast();
listeners[i].onWallpaperColorsChanged(wallpaperColors, which); for (int i = 0; i < count; i++) {
} catch (RemoteException e) { try {
// Callback is gone, it's not necessary to unregister it since currentUserColorListeners.getBroadcastItem(i)
// RemoteCallbackList#getBroadcastItem will take care of it. .onWallpaperColorsChanged(wallpaperColors, which, userId);
} catch (RemoteException e) {
// Callback is gone, it's not necessary to unregister it since
// RemoteCallbackList#getBroadcastItem will take care of it.
}
} }
currentUserColorListeners.finishBroadcast();
}
if (userAllColorListeners != null) {
int count = userAllColorListeners.beginBroadcast();
for (int i = 0; i < count; i++) {
try {
userAllColorListeners.getBroadcastItem(i)
.onWallpaperColorsChanged(wallpaperColors, which, userId);
} catch (RemoteException e) {
// Callback is gone, it's not necessary to unregister it since
// RemoteCallbackList#getBroadcastItem will take care of it.
}
}
userAllColorListeners.finishBroadcast();
} }
if (keyguardListener != null) { if (keyguardListener != null) {
try { try {
keyguardListener.onWallpaperColorsChanged(wallpaperColors, which); keyguardListener.onWallpaperColorsChanged(wallpaperColors, which, userId);
} catch (RemoteException e) { } catch (RemoteException e) {
// Oh well it went away; no big deal // Oh well it went away; no big deal
} }
@@ -595,7 +630,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
final IPackageManager mIPackageManager; final IPackageManager mIPackageManager;
final MyPackageMonitor mMonitor; final MyPackageMonitor mMonitor;
final AppOpsManager mAppOpsManager; final AppOpsManager mAppOpsManager;
final RemoteCallbackList<IWallpaperManagerCallback> mColorsChangedListeners; /**
* Map of color listeners per user id.
* The key will be the id of a user or UserHandle.USER_ALL - for wildcard listeners.
*/
final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> mColorsChangedListeners;
WallpaperData mLastWallpaper; WallpaperData mLastWallpaper;
IWallpaperManagerCallback mKeyguardListener; IWallpaperManagerCallback mKeyguardListener;
boolean mWaitingForUnlock; boolean mWaitingForUnlock;
@@ -858,11 +897,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
*/ */
@Override @Override
public void onWallpaperColorsChanged(WallpaperColors primaryColors) { public void onWallpaperColorsChanged(WallpaperColors primaryColors) {
// Do not override default color extraction if API isn't implemented.
if (primaryColors == null) {
return;
}
int which; int which;
synchronized (mLock) { synchronized (mLock) {
// Do not broadcast changes on ImageWallpaper since it's handled // Do not broadcast changes on ImageWallpaper since it's handled
@@ -876,7 +910,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
// Live wallpapers always are system wallpapers. // Live wallpapers always are system wallpapers.
which = FLAG_SYSTEM; which = FLAG_SYSTEM;
// It's also the lock screen wallpaper when we don't have a bitmap in there // It's also the lock screen wallpaper when we don't have a bitmap in there
WallpaperData lockedWallpaper = mLockWallpaperMap.get(mCurrentUserId); WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId);
if (lockedWallpaper == null) { if (lockedWallpaper == null) {
which |= FLAG_LOCK; which |= FLAG_LOCK;
} }
@@ -906,6 +940,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
} }
mPaddingChanged = false; mPaddingChanged = false;
} }
try {
// This will trigger onComputeColors in the wallpaper engine.
// It's fine to be locked in here since the binder is oneway.
mEngine.requestWallpaperColors();
} catch (RemoteException e) {
Slog.w(TAG, "Failed to request wallpaper colors", e);
}
} }
} }
@@ -1096,7 +1137,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
mMonitor.register(context, null, UserHandle.ALL, true); mMonitor.register(context, null, UserHandle.ALL, true);
getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs(); getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
loadSettingsLocked(UserHandle.USER_SYSTEM, false); loadSettingsLocked(UserHandle.USER_SYSTEM, false);
mColorsChangedListeners = new RemoteCallbackList<>(); mColorsChangedListeners = new SparseArray<>();
} }
private static File getWallpaperDir(int userId) { private static File getWallpaperDir(int userId) {
@@ -1252,16 +1293,24 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
} }
void switchUser(int userId, IRemoteCallback reply) { void switchUser(int userId, IRemoteCallback reply) {
WallpaperData systemWallpaper;
WallpaperData lockWallpaper;
synchronized (mLock) { synchronized (mLock) {
mCurrentUserId = userId; mCurrentUserId = userId;
WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM); systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
// Not started watching yet, in case wallpaper data was loaded for other reasons. lockWallpaper = mLockWallpaperMap.get(userId);
if (wallpaper.wallpaperObserver == null) { if (lockWallpaper == null) {
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper); lockWallpaper = systemWallpaper;
wallpaper.wallpaperObserver.startWatching();
} }
switchWallpaper(wallpaper, reply); // Not started watching yet, in case wallpaper data was loaded for other reasons.
if (systemWallpaper.wallpaperObserver == null) {
systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
systemWallpaper.wallpaperObserver.startWatching();
}
switchWallpaper(systemWallpaper, reply);
} }
notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
} }
void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) { void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
@@ -1634,16 +1683,30 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
} }
@Override @Override
public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb) { public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, true, true, "registerWallpaperColorsCallback", null);
synchronized (mLock) { synchronized (mLock) {
mColorsChangedListeners.register(cb); RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
mColorsChangedListeners.get(userId);
if (userColorsChangedListeners == null) {
userColorsChangedListeners = new RemoteCallbackList<>();
mColorsChangedListeners.put(userId, userColorsChangedListeners);
}
userColorsChangedListeners.register(cb);
} }
} }
@Override @Override
public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb) { public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, true, true, "unregisterWallpaperColorsCallback", null);
synchronized (mLock) { synchronized (mLock) {
mColorsChangedListeners.unregister(cb); final RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
mColorsChangedListeners.get(userId);
if (userColorsChangedListeners != null) {
userColorsChangedListeners.unregister(cb);
}
} }
} }
@@ -1657,23 +1720,25 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
} }
@Override @Override
public WallpaperColors getWallpaperColors(int which) throws RemoteException { public WallpaperColors getWallpaperColors(int which, int userId) throws RemoteException {
if (which != FLAG_LOCK && which != FLAG_SYSTEM) { if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM"); throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM");
} }
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, true, "getWallpaperColors", null);
WallpaperData wallpaperData = null; WallpaperData wallpaperData = null;
boolean shouldExtract; boolean shouldExtract;
synchronized (mLock) { synchronized (mLock) {
if (which == FLAG_LOCK) { if (which == FLAG_LOCK) {
wallpaperData = mLockWallpaperMap.get(mCurrentUserId); wallpaperData = mLockWallpaperMap.get(userId);
} }
// Try to get the system wallpaper anyway since it might // Try to get the system wallpaper anyway since it might
// also be the lock screen wallpaper // also be the lock screen wallpaper
if (wallpaperData == null) { if (wallpaperData == null) {
wallpaperData = mWallpaperMap.get(mCurrentUserId); wallpaperData = mWallpaperMap.get(userId);
} }
if (wallpaperData == null) { if (wallpaperData == null) {
@@ -1872,8 +1937,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
try { try {
wallpaper.imageWallpaperPending = false; wallpaper.imageWallpaperPending = false;
boolean same = changingToSame(name, wallpaper);
if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) { if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
wallpaper.primaryColors = null; if (!same) {
wallpaper.primaryColors = null;
}
wallpaper.wallpaperId = makeWallpaperIdLocked(); wallpaper.wallpaperId = makeWallpaperIdLocked();
notifyCallbacksLocked(wallpaper); notifyCallbacksLocked(wallpaper);
shouldNotifyColors = true; shouldNotifyColors = true;
@@ -1888,26 +1956,31 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
} }
} }
private boolean changingToSame(ComponentName componentName, WallpaperData wallpaper) {
if (wallpaper.connection != null) {
if (wallpaper.wallpaperComponent == null) {
if (componentName == null) {
if (DEBUG) Slog.v(TAG, "changingToSame: still using default");
// Still using default wallpaper.
return true;
}
} else if (wallpaper.wallpaperComponent.equals(componentName)) {
// Changing to same wallpaper.
if (DEBUG) Slog.v(TAG, "same wallpaper");
return true;
}
}
return false;
}
boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force, boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) { boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) {
if (DEBUG_LIVE) { if (DEBUG_LIVE) {
Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName); Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
} }
// Has the component changed? // Has the component changed?
if (!force) { if (!force && changingToSame(componentName, wallpaper)) {
if (wallpaper.connection != null) { return true;
if (wallpaper.wallpaperComponent == null) {
if (componentName == null) {
if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
// Still using default wallpaper.
return true;
}
} else if (wallpaper.wallpaperComponent.equals(componentName)) {
// Changing to same wallpaper.
if (DEBUG) Slog.v(TAG, "same wallpaper");
return true;
}
}
} }
try { try {