Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adb6b168 authored by Jay Aliomer's avatar Jay Aliomer Committed by Android (Google) Code Review
Browse files

Merge "Local Wallpaper Color high resource usage" into sc-dev

parents dfd02710 6bb6687f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -167,7 +167,8 @@ interface IWallpaperManager {
    * @hide
    */
    void removeOnLocalColorsChangedListener(
            in ILocalWallpaperColorConsumer callback, int which, int userId, int displayId);
            in ILocalWallpaperColorConsumer callback, in List<RectF> area,
            int which, int userId, int displayId);

    /**
    * @hide
+40 −18
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import android.os.StrictMode;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
import android.view.Display;
@@ -318,8 +319,20 @@ public class WallpaperManager {
        private int mCachedWallpaperUserId;
        private Bitmap mDefaultWallpaper;
        private Handler mMainLooperHandler;
        private ArrayMap<LocalWallpaperColorConsumer, ILocalWallpaperColorConsumer>
                mLocalColorCallbacks = new ArrayMap<>();
        private ArrayMap<RectF, ArraySet<LocalWallpaperColorConsumer>> mLocalColorAreas =
                new ArrayMap<>();
        private ILocalWallpaperColorConsumer mLocalColorCallback =
                new ILocalWallpaperColorConsumer.Stub() {
                    @Override
                    public void onColorsChanged(RectF area, WallpaperColors colors) {
                        ArraySet<LocalWallpaperColorConsumer> callbacks =
                                mLocalColorAreas.get(area);
                        if (callbacks == null) return;
                        for (LocalWallpaperColorConsumer callback: callbacks) {
                            callback.onColorsChanged(area, colors);
                        }
                    }
                };

        Globals(IWallpaperManager service, Looper looper) {
            mService = service;
@@ -361,37 +374,46 @@ public class WallpaperManager {
            }
        }

        private ILocalWallpaperColorConsumer wrap(LocalWallpaperColorConsumer callback) {
            ILocalWallpaperColorConsumer callback2 = new ILocalWallpaperColorConsumer.Stub() {
                @Override
                public void onColorsChanged(RectF area, WallpaperColors colors) {
                    callback.onColorsChanged(area, colors);
                }
            };
            mLocalColorCallbacks.put(callback, callback2);
            return callback2;
        }

        public void addOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback,
                @NonNull List<RectF> regions, int which, int userId, int displayId) {
            for (RectF area: regions) {
                ArraySet<LocalWallpaperColorConsumer> callbacks = mLocalColorAreas.get(area);
                if (callbacks == null) {
                    callbacks = new ArraySet<>();
                    mLocalColorAreas.put(area, callbacks);
                }
                callbacks.add(callback);
            }
            try {
                mService.addOnLocalColorsChangedListener(wrap(callback) , regions, which,
                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) {
            ILocalWallpaperColorConsumer callback2 = mLocalColorCallbacks.remove(callback);
            if (callback2 == null) return;
            final ArrayList<RectF> removeAreas = new ArrayList<>();
            for (RectF area : mLocalColorAreas.keySet()) {
                ArraySet<LocalWallpaperColorConsumer> callbacks = mLocalColorAreas.get(area);
                if (callbacks == null) continue;
                callbacks.remove(callback);
                if (callbacks.size() == 0) {
                    mLocalColorAreas.remove(area);
                    removeAreas.add(area);
                }
            }
            try {
                if (removeAreas.size() > 0) {
                    mService.removeOnLocalColorsChangedListener(
                        callback2, which, userId, displayId);
                            mLocalColorCallback, removeAreas, which, userId, displayId);
                }
            } catch (RemoteException e) {
                // Can't get colors, connection lost.
                Log.e(TAG, "Can't unregister for local color updates", e);
            }
        }

+28 −27
Original line number Diff line number Diff line
@@ -90,7 +90,6 @@ import android.system.Os;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -2447,8 +2446,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub

    @Override
    public void removeOnLocalColorsChangedListener(
            @NonNull ILocalWallpaperColorConsumer callback, int which, int userId,
            int displayId) throws RemoteException {
            @NonNull ILocalWallpaperColorConsumer callback, List<RectF> removeAreas, 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");
        }
@@ -2457,43 +2456,45 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
            throw new SecurityException("calling user id does not match");
        }
        final long identity = Binder.clearCallingIdentity();
        ArrayList<RectF> removeAreas = new ArrayList<>();
        ArrayList<Pair<RemoteCallbackList, ILocalWallpaperColorConsumer>>
                callbacksToRemove = new ArrayList<>();
        ArrayList<RectF> purgeAreas = new ArrayList<>();
        IBinder binder = callback.asBinder();
        try {
            synchronized (mLock) {
                ArraySet<RectF> areas = mLocalColorCallbackAreas.remove(callback.asBinder());
                mLocalColorCallbackDisplayId.remove(callback.asBinder());
                if (areas == null) areas = new ArraySet<>();
                for (RectF area : areas) {
                    RemoteCallbackList callbacks = mLocalColorAreaCallbacks.get(area);
                    if (callbacks == null) continue;
                    callbacksToRemove.add(new Pair<>(callbacks, callback));
                    if (callbacks.getRegisteredCallbackCount() == 0) {
                        mLocalColorAreaCallbacks.remove(area);
                        removeAreas.add(area);
                    }
                ArraySet<RectF> currentAreas = mLocalColorCallbackAreas.get(binder);
                if (currentAreas == null) return;
                currentAreas.removeAll(removeAreas);
                if (currentAreas.size() == 0) {
                    mLocalColorCallbackDisplayId.remove(binder);
                    for (RectF removeArea : removeAreas) {
                        RemoteCallbackList<ILocalWallpaperColorConsumer> remotes =
                                mLocalColorAreaCallbacks.get(removeArea);
                        if (remotes == null) continue;
                        remotes.unregister(callback);
                        if (remotes.getRegisteredCallbackCount() == 0) {
                            mLocalColorAreaCallbacks.remove(removeArea);
                            purgeAreas.add(removeArea);
                            ArraySet<RectF> displayAreas = mLocalColorDisplayIdAreas.get(displayId);
                            if (displayAreas != null) {
                        displayAreas.remove(area);
                                displayAreas.remove(removeArea);
                                if (displayAreas.size() == 0) {
                                    mLocalColorDisplayIdAreas.remove(displayId);
                                }
                            }
                        }
                    }
            for (int i = 0; i < callbacksToRemove.size(); i++) {
                Pair<RemoteCallbackList, ILocalWallpaperColorConsumer>
                        pair = callbacksToRemove.get(i);
                pair.first.unregister(pair.second);
                }
            }

        } catch (Exception e) {
            // ignore any exception
        } finally {
            Binder.restoreCallingIdentity(identity);
        }

        if (removeAreas.size() == 0) return;
        if (purgeAreas.size() == 0) return;
        IWallpaperEngine engine = getEngine(which, userId, displayId);
        if (engine == null) return;
        engine.removeLocalColorsAreas(removeAreas);
        engine.removeLocalColorsAreas(purgeAreas);
    }

    @Override