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

Commit 73f66f06 authored by Sunny Goyal's avatar Sunny Goyal Committed by Pierre Barbier de Reuille
Browse files

Accounting for image scaling when calculating color extraction

> Also caching display size instead of making RPC in every frame

Bug: 194232172
Fix: 195435616
Test: Manual
Change-Id: I1b71a2316e7b8b7fde6190abd75be89330e2d051
(cherry picked from commit 00471fb4)
parent 0650029a
Loading
Loading
Loading
Loading
+51 −33
Original line number Original line Diff line number Diff line
@@ -20,6 +20,8 @@ import android.app.WallpaperColors;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.RectF;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.os.SystemClock;
@@ -29,7 +31,6 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.Log;
import android.util.MathUtils;
import android.util.MathUtils;
import android.util.Size;
import android.util.Size;
import android.view.DisplayInfo;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder;
import android.view.WindowManager;
import android.view.WindowManager;


@@ -90,7 +91,7 @@ public class ImageWallpaper extends WallpaperService {
        mMiniBitmap = null;
        mMiniBitmap = null;
    }
    }


    class GLEngine extends Engine {
    class GLEngine extends Engine implements DisplayListener {
        // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
        // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
        // set min to 64 px (CTS covers this), please refer to ag/4867989 for detail.
        // set min to 64 px (CTS covers this), please refer to ag/4867989 for detail.
        @VisibleForTesting
        @VisibleForTesting
@@ -102,15 +103,15 @@ public class ImageWallpaper extends WallpaperService {
        private EglHelper mEglHelper;
        private EglHelper mEglHelper;
        private final Runnable mFinishRenderingTask = this::finishRendering;
        private final Runnable mFinishRenderingTask = this::finishRendering;
        private boolean mNeedRedraw;
        private boolean mNeedRedraw;
        private int mWidth = 1;

        private int mHeight = 1;
        private boolean mDisplaySizeValid = false;
        private int mDisplayWidth = 1;
        private int mDisplayHeight = 1;

        private int mImgWidth = 1;
        private int mImgWidth = 1;
        private int mImgHeight = 1;
        private int mImgHeight = 1;
        private float mPageWidth = 1.f;
        private float mPageOffset = 1.f;


        GLEngine() {
        GLEngine() { }
        }


        @VisibleForTesting
        @VisibleForTesting
        GLEngine(Handler handler) {
        GLEngine(Handler handler) {
@@ -124,13 +125,23 @@ public class ImageWallpaper extends WallpaperService {
            mRenderer = getRendererInstance();
            mRenderer = getRendererInstance();
            setFixedSizeAllowed(true);
            setFixedSizeAllowed(true);
            updateSurfaceSize();
            updateSurfaceSize();
            Rect window = getDisplayContext()

                    .getSystemService(WindowManager.class)
                    .getCurrentWindowMetrics()
                    .getBounds();
            mHeight = window.height();
            mWidth = window.width();
            mRenderer.setOnBitmapChanged(this::updateMiniBitmap);
            mRenderer.setOnBitmapChanged(this::updateMiniBitmap);
            getDisplayContext().getSystemService(DisplayManager.class)
                    .registerDisplayListener(this, mWorker.getThreadHandler());
        }

        @Override
        public void onDisplayAdded(int displayId) { }

        @Override
        public void onDisplayRemoved(int displayId) { }

        @Override
        public void onDisplayChanged(int displayId) {
            if (displayId == getDisplayContext().getDisplayId()) {
                mDisplaySizeValid = false;
            }
        }
        }


        EglHelper getEglHelperInstance() {
        EglHelper getEglHelperInstance() {
@@ -154,26 +165,10 @@ public class ImageWallpaper extends WallpaperService {
            if (pages == mPages) return;
            if (pages == mPages) return;
            mPages = pages;
            mPages = pages;
            if (mMiniBitmap == null || mMiniBitmap.isRecycled()) return;
            if (mMiniBitmap == null || mMiniBitmap.isRecycled()) return;
            updateShift();
            mWorker.getThreadHandler().post(() ->
            mWorker.getThreadHandler().post(() ->
                    computeAndNotifyLocalColors(new ArrayList<>(mColorAreas), mMiniBitmap));
                    computeAndNotifyLocalColors(new ArrayList<>(mColorAreas), mMiniBitmap));
        }
        }


        private void updateShift() {
            if (mImgHeight == 0) {
                mPageOffset = 0;
                mPageWidth = 1;
                return;
            }
            // calculate shift
            DisplayInfo displayInfo = new DisplayInfo();
            getDisplayContext().getDisplay().getDisplayInfo(displayInfo);
            int screenWidth = displayInfo.getNaturalWidth();
            float imgWidth = Math.min(mImgWidth > 0 ? screenWidth / (float) mImgWidth : 1.f, 1.f);
            mPageWidth = imgWidth;
            mPageOffset = (1 - imgWidth) / (float) (mPages - 1);
        }

        private void updateMiniBitmap(Bitmap b) {
        private void updateMiniBitmap(Bitmap b) {
            if (b == null) return;
            if (b == null) return;
            int size = Math.min(b.getWidth(), b.getHeight());
            int size = Math.min(b.getWidth(), b.getHeight());
@@ -204,6 +199,8 @@ public class ImageWallpaper extends WallpaperService {


        @Override
        @Override
        public void onDestroy() {
        public void onDestroy() {
            getDisplayContext().getSystemService(DisplayManager.class)
                    .unregisterDisplayListener(this);
            mMiniBitmap = null;
            mMiniBitmap = null;
            mWorker.getThreadHandler().post(() -> {
            mWorker.getThreadHandler().post(() -> {
                mRenderer.finish();
                mRenderer.finish();
@@ -268,6 +265,16 @@ public class ImageWallpaper extends WallpaperService {
         * (1-Wr)].
         * (1-Wr)].
         */
         */
        private RectF pageToImgRect(RectF area) {
        private RectF pageToImgRect(RectF area) {
            if (!mDisplaySizeValid) {
                Rect window = getDisplayContext()
                        .getSystemService(WindowManager.class)
                        .getCurrentWindowMetrics()
                        .getBounds();
                mDisplayWidth = window.width();
                mDisplayHeight = window.height();
                mDisplaySizeValid = true;
            }

            // Width of a page for the caller of this API.
            // Width of a page for the caller of this API.
            float virtualPageWidth = 1f / (float) mPages;
            float virtualPageWidth = 1f / (float) mPages;
            float leftPosOnPage = (area.left % virtualPageWidth) / virtualPageWidth;
            float leftPosOnPage = (area.left % virtualPageWidth) / virtualPageWidth;
@@ -275,12 +282,24 @@ public class ImageWallpaper extends WallpaperService {
            int currentPage = (int) Math.floor(area.centerX() / virtualPageWidth);
            int currentPage = (int) Math.floor(area.centerX() / virtualPageWidth);


            RectF imgArea = new RectF();
            RectF imgArea = new RectF();

            if (mImgWidth == 0 || mImgHeight == 0 || mDisplayWidth <= 0 || mDisplayHeight <= 0) {
                return imgArea;
            }

            imgArea.bottom = area.bottom;
            imgArea.bottom = area.bottom;
            imgArea.top = area.top;
            imgArea.top = area.top;

            float imageScale = Math.min(((float) mImgHeight) / mDisplayHeight, 1);
            float mappedScreenWidth = mDisplayWidth * imageScale;
            float pageWidth = Math.min(1.0f,
                    mImgWidth > 0 ? mappedScreenWidth / (float) mImgWidth : 1.f);
            float pageOffset = (1 - pageWidth) / (float) (mPages - 1);

            imgArea.left = MathUtils.constrain(
            imgArea.left = MathUtils.constrain(
                    leftPosOnPage * mPageWidth + currentPage * mPageOffset, 0, 1);
                    leftPosOnPage * pageWidth + currentPage * pageOffset, 0, 1);
            imgArea.right = MathUtils.constrain(
            imgArea.right = MathUtils.constrain(
                    rightPosOnPage * mPageWidth + currentPage * mPageOffset, 0, 1);
                    rightPosOnPage * pageWidth + currentPage * pageOffset, 0, 1);
            if (imgArea.left > imgArea.right) {
            if (imgArea.left > imgArea.right) {
                // take full page
                // take full page
                imgArea.left = 0;
                imgArea.left = 0;
@@ -293,7 +312,6 @@ public class ImageWallpaper extends WallpaperService {
        private List<WallpaperColors> getLocalWallpaperColors(@NonNull List<RectF> areas,
        private List<WallpaperColors> getLocalWallpaperColors(@NonNull List<RectF> areas,
                Bitmap b) {
                Bitmap b) {
            List<WallpaperColors> colors = new ArrayList<>(areas.size());
            List<WallpaperColors> colors = new ArrayList<>(areas.size());
            updateShift();
            for (int i = 0; i < areas.size(); i++) {
            for (int i = 0; i < areas.size(); i++) {
                RectF area = pageToImgRect(areas.get(i));
                RectF area = pageToImgRect(areas.get(i));
                if (area == null || !LOCAL_COLOR_BOUNDS.contains(area)) {
                if (area == null || !LOCAL_COLOR_BOUNDS.contains(area)) {