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

Commit 5abc71b2 authored by wilsonshih's avatar wilsonshih Committed by Lucas Dupin
Browse files

Improve the performance when loading image wallpaper colors

When SystemUI start up, ColorExtractor will get wallpaper colors so
status bar can use it to update theme, however, this will also block
SystemUI start up process if the wallpaper is image wallpaper.
In order to break the latency, we can extract getWallpaperColors
method from ColorExtractor's contructor, and do it at another thread,
so it won't block SystemUI start up.

Bug: 124279857
Test: atest ColorExtractorTest
Test: Manual test change theme feature can work normally.
Merged-In: I8589b28a17b0a2b33b4bbbda2265080af983f26a
Change-Id: I8589b28a17b0a2b33b4bbbda2265080af983f26a
parent 8098c5f1
Loading
Loading
Loading
Loading
+34 −11
Original line number Diff line number Diff line
@@ -21,8 +21,7 @@ import android.annotation.Nullable;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.content.Context;
import android.os.Trace;
import android.os.UserHandle;
import android.os.AsyncTask;
import android.util.Log;
import android.util.SparseArray;

@@ -32,7 +31,6 @@ import com.android.internal.colorextraction.types.Tonal;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Class to process wallpaper colors and generate a tonal palette based on them.
@@ -55,11 +53,11 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
    protected WallpaperColors mLockColors;

    public ColorExtractor(Context context) {
        this(context, new Tonal(context));
        this(context, new Tonal(context), true /* immediately */);
    }

    @VisibleForTesting
    public ColorExtractor(Context context, ExtractionType extractionType) {
    public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately) {
        mContext = context;
        mExtractionType = extractionType;

@@ -73,23 +71,48 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
        }

        mOnColorsChangedListeners = new ArrayList<>();
        GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
        GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);

        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
        if (wallpaperManager == null) {
            Log.w(TAG, "Can't listen to color changes!");
        } else {
            wallpaperManager.addOnColorsChangedListener(this, null /* handler */);
            initExtractColors(wallpaperManager, immediately);
        }
    }

            // Initialize all gradients with the current colors
            Trace.beginSection("ColorExtractor#getWallpaperColors");
    private void initExtractColors(WallpaperManager wallpaperManager, boolean immediately) {
        if (immediately) {
            mSystemColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
            mLockColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK);
            Trace.endSection();
            extractWallpaperColors();
        } else {
            new LoadWallpaperColors().executeOnExecutor(
                    AsyncTask.THREAD_POOL_EXECUTOR, wallpaperManager);
        }
    }

    private class LoadWallpaperColors extends AsyncTask<WallpaperManager, Void, Void> {
        private WallpaperColors mSystemColors;
        private WallpaperColors mLockColors;
        @Override
        protected Void doInBackground(WallpaperManager... params) {
            mSystemColors = params[0].getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
            mLockColors = params[0].getWallpaperColors(WallpaperManager.FLAG_LOCK);
            return null;
        }
        @Override
        protected void onPostExecute(Void b) {
            ColorExtractor.this.mSystemColors = mSystemColors;
            ColorExtractor.this.mLockColors = mLockColors;
            extractWallpaperColors();
            triggerColorsChanged(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
        }
    }

        // Initialize all gradients with the current colors
    private void extractWallpaperColors() {
        GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
        GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
        extractInto(mSystemColors,
                systemColors[TYPE_NORMAL],
                systemColors[TYPE_DARK],
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable {

    @VisibleForTesting
    public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) {
        super(context, type);
        super(context, type, false /* immediately */);
        mWpHiddenColors = new GradientColors();

        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+3 −3
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ public class ColorExtractorTest {
    @Test
    public void ColorExtractor_extractWhenInitialized() {
        ExtractionType type = mock(Tonal.class);
        new ColorExtractor(mContext, type);
        new ColorExtractor(mContext, type, true);
        // 1 for lock and 1 for system
        verify(type, times(2))
                .extractInto(any(), any(), any(), any());
@@ -83,7 +83,7 @@ public class ColorExtractorTest {
                    outGradientColorsDark.set(colorsExpectedDark);
                    outGradientColorsExtraDark.set(colorsExpectedExtraDark);
                };
        ColorExtractor extractor = new ColorExtractor(mContext, type);
        ColorExtractor extractor = new ColorExtractor(mContext, type, true);

        GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM,
                ColorExtractor.TYPE_NORMAL);
@@ -98,7 +98,7 @@ public class ColorExtractorTest {
    public void addOnColorsChangedListener_invokesListener() {
        ColorExtractor.OnColorsChangedListener mockedListeners =
                mock(ColorExtractor.OnColorsChangedListener.class);
        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext));
        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true);
        extractor.addOnColorsChangedListener(mockedListeners);

        extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),