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

Commit 416fe954 authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Improved WallpaperService.Engine tests

Using final variables when possible, also testing if
overlaping invalidation requests will be posted to
the handler.

Bug: 63585249
Test: runtest -x services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java
Change-Id: I01cdbdfd5313e55d7a58c77f705aea0f6f817518
parent e25757a1
Loading
Loading
Loading
Loading
+25 −13
Original line number Diff line number Diff line
@@ -195,7 +195,8 @@ public abstract class WallpaperService extends Service {
        // Needed for throttling onComputeColors.
        private long mLastColorInvalidation;
        private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
        private Supplier<Long> mClockFunction = SystemClock::elapsedRealtime;
        private final Supplier<Long> mClockFunction;
        private final Handler mHandler;

        DisplayManager mDisplayManager;
        Display mDisplay;
@@ -363,6 +364,26 @@ public abstract class WallpaperService extends Service {
            }
        };

        /**
         * Default constructor
         */
        public Engine() {
            this(SystemClock::elapsedRealtime, Handler.getMain());
        }

        /**
         * Constructor used for test purposes.
         *
         * @param clockFunction Supplies current times in millis.
         * @param handler Used for posting/deferring asynchronous calls.
         * @hide
         */
        @VisibleForTesting
        public Engine(Supplier<Long> clockFunction, Handler handler) {
           mClockFunction = clockFunction;
           mHandler = handler;
        }
        
        /**
         * Provides access to the surface in which this wallpaper is drawn.
         */
@@ -563,18 +584,17 @@ public abstract class WallpaperService extends Service {
         */
        public void notifyColorsChanged() {
            final long now = mClockFunction.get();
            final Handler mainHandler = Handler.getMain();
            if (now - mLastColorInvalidation < NOTIFY_COLORS_RATE_LIMIT_MS) {
                Log.w(TAG, "This call has been deferred. You should only call "
                        + "notifyColorsChanged() once every "
                        + (NOTIFY_COLORS_RATE_LIMIT_MS / 1000f) + " seconds.");
                if (!mainHandler.hasCallbacks(mNotifyColorsChanged)) {
                    mainHandler.postDelayed(mNotifyColorsChanged, NOTIFY_COLORS_RATE_LIMIT_MS);
                if (!mHandler.hasCallbacks(mNotifyColorsChanged)) {
                    mHandler.postDelayed(mNotifyColorsChanged, NOTIFY_COLORS_RATE_LIMIT_MS);
                }
                return;
            }
            mLastColorInvalidation = now;
            mainHandler.removeCallbacks(mNotifyColorsChanged);
            mHandler.removeCallbacks(mNotifyColorsChanged);

            try {
                final WallpaperColors newColors = onComputeColors();
@@ -662,14 +682,6 @@ public abstract class WallpaperService extends Service {
            }
        }

        /**
         * @hide
         */
        @VisibleForTesting
        public void setClockFunction(Supplier<Long> clockFunction) {
            mClockFunction = clockFunction;
        }

        void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
            if (mDestroyed) {
                Log.w(TAG, "Ignoring updateSurface: destroyed");
+23 −3
Original line number Diff line number Diff line
@@ -17,10 +17,14 @@
package com.android.server.wallpaper;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import android.app.WallpaperColors;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.service.wallpaper.WallpaperService;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

@@ -28,18 +32,31 @@ import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.CountDownLatch;
import java.util.function.Supplier;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class WallpaperServiceTests {

    @UiThreadTest
    @Test
    public void testNotifyColorsChanged_rateLimit() throws Exception {
        long[] clockOffset = {0};
        boolean[] postDelayed = {false};
        Supplier<Long> clockFunction = () -> SystemClock.elapsedRealtime() + clockOffset[0];
        Handler handler = new Handler() {
            @Override
            public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
                postDelayed[0] = true;
                return super.sendMessageAtTime(msg, uptimeMillis);
            }
        };

        CountDownLatch eventCountdown = new CountDownLatch(2);
        WallpaperService service = new WallpaperService() {
            @Override
            public Engine onCreateEngine() {
                return new WallpaperService.Engine() {
                return new WallpaperService.Engine(clockFunction, handler) {
                    @Override
                    public WallpaperColors onComputeColors() {
                        eventCountdown.countDown();
@@ -59,8 +76,11 @@ public class WallpaperServiceTests {
        engine.notifyColorsChanged();
        assertEquals("OnComputeColors should have been throttled.",
                1, eventCountdown.getCount());
        // Called after being deferred.
        engine.setClockFunction(() ->  SystemClock.elapsedRealtime() + 1500);
        // Should have been posted to the handler.
        assertTrue("Event should have been delayed", postDelayed[0]);

        // Called again after being deferred.
        clockOffset[0] = 1500;
        engine.notifyColorsChanged();
        assertEquals("OnComputeColors should have been deferred.",
                0, eventCountdown.getCount());