From 0e490d9e77c2ede86e34074d30af2d9c4c754e72 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Wed, 13 Feb 2019 12:20:01 +0800 Subject: [PATCH] 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. Change-Id: I8589b28a17b0a2b33b4bbbda2265080af983f26a --- .../colorextraction/ColorExtractor.java | 43 +++++++++++++++---- .../colorextraction/SysuiColorExtractor.java | 2 +- .../colorextraction/ColorExtractorTest.java | 6 +-- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index 258d081c6ad89..d9fd3b5bd6d82 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -21,7 +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.AsyncTask; import android.util.Log; import android.util.SparseArray; @@ -53,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; @@ -71,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); } + } - // Initialize all gradients with the current colors + private class LoadWallpaperColors extends AsyncTask { + 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); + } + } + + 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], diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java index 900ea72d856c0..a74c3287e1f12 100644 --- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java @@ -61,7 +61,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 */); mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context); mWpHiddenColors = new GradientColors(); diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java index cb6a83d2644b0..39608a40b4166 100644 --- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java +++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java @@ -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),