From 2eaae4e670a1dc8a38806676a8a3aba134766ff7 Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Tue, 23 Nov 2021 15:51:59 -0500 Subject: Properly remove local color areas of callback Refactored to system server to the repository pattern added locks to the WallpaperManager Fixes: 206632865 Test: manual Change-Id: Icc73c18e34042ae48e338b03dc3e94fee5d6939d --- core/java/android/app/WallpaperManager.java | 81 ++++++++++++++++------------- 1 file changed, 44 insertions(+), 37 deletions(-) (limited to 'core/java/android') diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 22b1c03fba50..fca4c698c49c 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -365,17 +365,18 @@ public class WallpaperManager { private int mCachedWallpaperUserId; private Bitmap mDefaultWallpaper; private Handler mMainLooperHandler; - private ArrayMap> mLocalColorAreas = - new ArrayMap<>(); + private ArrayMap> mLocalColorCallbackAreas = + new ArrayMap<>(); private ILocalWallpaperColorConsumer mLocalColorCallback = new ILocalWallpaperColorConsumer.Stub() { @Override public void onColorsChanged(RectF area, WallpaperColors colors) { - ArraySet callbacks = - mLocalColorAreas.get(area); - if (callbacks == null) return; - for (LocalWallpaperColorConsumer callback: callbacks) { - callback.onColorsChanged(area, colors); + for (LocalWallpaperColorConsumer callback : + mLocalColorCallbackAreas.keySet()) { + ArraySet areas = mLocalColorCallbackAreas.get(callback); + if (areas != null && areas.contains(area)) { + callback.onColorsChanged(area, colors); + } } } }; @@ -420,46 +421,52 @@ public class WallpaperManager { } } - public void addOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback, + public void addOnColorsChangedListener( + @NonNull LocalWallpaperColorConsumer callback, @NonNull List regions, int which, int userId, int displayId) { - for (RectF area: regions) { - ArraySet callbacks = mLocalColorAreas.get(area); - if (callbacks == null) { - callbacks = new ArraySet<>(); - mLocalColorAreas.put(area, callbacks); + synchronized (this) { + for (RectF area : regions) { + ArraySet areas = mLocalColorCallbackAreas.get(callback); + if (areas == null) { + areas = new ArraySet<>(); + mLocalColorCallbackAreas.put(callback, areas); + } + areas.add(area); + } + try { + // one way returns immediately + mService.addOnLocalColorsChangedListener(mLocalColorCallback, regions, which, + userId, displayId); + } catch (RemoteException e) { + // Can't get colors, connection lost. + Log.e(TAG, "Can't register for local color updates", e); } - callbacks.add(callback); - } - try { - mService.addOnLocalColorsChangedListener(mLocalColorCallback , regions, which, - userId, displayId); - } catch (RemoteException e) { - // Can't get colors, connection lost. - Log.e(TAG, "Can't register for local color updates", e); } } public void removeOnColorsChangedListener( @NonNull LocalWallpaperColorConsumer callback, int which, int userId, int displayId) { - final ArrayList removeAreas = new ArrayList<>(); - for (RectF area : mLocalColorAreas.keySet()) { - ArraySet callbacks = mLocalColorAreas.get(area); - if (callbacks == null) continue; - callbacks.remove(callback); - if (callbacks.size() == 0) { - mLocalColorAreas.remove(area); - removeAreas.add(area); + synchronized (this) { + final ArraySet removeAreas = mLocalColorCallbackAreas.remove(callback); + if (removeAreas == null || removeAreas.size() == 0) { + return; } - } - try { - if (removeAreas.size() > 0) { - mService.removeOnLocalColorsChangedListener( - mLocalColorCallback, removeAreas, which, userId, displayId); + for (LocalWallpaperColorConsumer cb : mLocalColorCallbackAreas.keySet()) { + ArraySet areas = mLocalColorCallbackAreas.get(cb); + if (areas != null && cb != callback) removeAreas.removeAll(areas); + } + try { + if (removeAreas.size() > 0) { + // one way returns immediately + mService.removeOnLocalColorsChangedListener( + mLocalColorCallback, new ArrayList(removeAreas), which, userId, + displayId); + } + } catch (RemoteException e) { + // Can't get colors, connection lost. + Log.e(TAG, "Can't unregister for local color updates", e); } - } catch (RemoteException e) { - // Can't get colors, connection lost. - Log.e(TAG, "Can't unregister for local color updates", e); } } -- cgit v1.2.3