Merge "Started converting Launcher to be gesture-stable" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/NormalizedIconLoader.java b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
index f875bb7..a4a2e56 100644
--- a/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
+++ b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
@@ -42,12 +42,15 @@
private final SparseArray<BitmapInfo> mDefaultIcons = new SparseArray<>();
private final DrawableFactory mDrawableFactory;
+ private final boolean mDisableColorExtraction;
private LauncherIcons mLauncherIcons;
public NormalizedIconLoader(Context context, TaskKeyLruCache<Drawable> iconCache,
- LruCache<ComponentName, ActivityInfo> activityInfoCache) {
+ LruCache<ComponentName, ActivityInfo> activityInfoCache,
+ boolean disableColorExtraction) {
super(context, iconCache, activityInfoCache);
mDrawableFactory = DrawableFactory.get(context);
+ mDisableColorExtraction = disableColorExtraction;
}
@Override
@@ -74,6 +77,9 @@
int primaryColor, boolean isInstantApp) {
if (mLauncherIcons == null) {
mLauncherIcons = LauncherIcons.obtain(mContext);
+ if (mDisableColorExtraction) {
+ mLauncherIcons.disableColorExtraction();
+ }
}
mLauncherIcons.setWrapperBackgroundColor(primaryColor);
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index fa4e016..a9b7326 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -94,7 +94,9 @@
protected IconLoader createNewIconLoader(Context context,
TaskKeyLruCache<Drawable> iconCache,
LruCache<ComponentName, ActivityInfo> activityInfoCache) {
- return new NormalizedIconLoader(context, iconCache, activityInfoCache);
+ // Disable finding the dominant color since we don't need to use it
+ return new NormalizedIconLoader(context, iconCache, activityInfoCache,
+ true /* disableColorExtraction */);
}
};
mRecentsTaskLoader.startLoader(mContext);
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index d6635dc..f5fbf80 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -19,7 +19,9 @@
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
import android.content.Intent;
+import android.content.res.Configuration;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.os.StrictMode;
@@ -81,13 +83,33 @@
@Override
public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
+ updateTheme();
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ updateTheme();
+ }
+
+ private void updateTheme() {
+ WallpaperColorInfo wallpaperColorInfo = WallpaperColorInfo.getInstance(this);
if (mThemeRes != getThemeRes(wallpaperColorInfo)) {
recreate();
}
}
protected int getThemeRes(WallpaperColorInfo wallpaperColorInfo) {
- if (wallpaperColorInfo.isDark()) {
+ boolean darkTheme;
+ if (Utilities.ATLEAST_Q) {
+ Configuration configuration = getResources().getConfiguration();
+ int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ darkTheme = nightMode == Configuration.UI_MODE_NIGHT_YES;
+ } else {
+ darkTheme = wallpaperColorInfo.isDark();
+ }
+
+ if (darkTheme) {
return wallpaperColorInfo.supportsDarkText() ?
R.style.AppTheme_Dark_DarkText : R.style.AppTheme_Dark;
} else {
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index a851318..1c12464 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -83,6 +83,10 @@
private static final Matrix sMatrix = new Matrix();
private static final Matrix sInverseMatrix = new Matrix();
+ public static final boolean ATLEAST_Q = Build.VERSION.CODENAME.length() == 1
+ && Build.VERSION.CODENAME.charAt(0) >= 'Q'
+ && Build.VERSION.CODENAME.charAt(0) <= 'Z';
+
public static final boolean ATLEAST_P =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
diff --git a/src/com/android/launcher3/graphics/BitmapInfo.java b/src/com/android/launcher3/graphics/BitmapInfo.java
index ab906e2..c905a78 100644
--- a/src/com/android/launcher3/graphics/BitmapInfo.java
+++ b/src/com/android/launcher3/graphics/BitmapInfo.java
@@ -35,9 +35,15 @@
}
public static BitmapInfo fromBitmap(Bitmap bitmap) {
+ return fromBitmap(bitmap, null);
+ }
+
+ public static BitmapInfo fromBitmap(Bitmap bitmap, ColorExtractor dominantColorExtractor) {
BitmapInfo info = new BitmapInfo();
info.icon = bitmap;
- info.color = ColorExtractor.findDominantColorByHue(bitmap);
+ info.color = dominantColorExtractor != null
+ ? dominantColorExtractor.findDominantColorByHue(bitmap)
+ : 0;
return info;
}
}
diff --git a/src/com/android/launcher3/graphics/ColorExtractor.java b/src/com/android/launcher3/graphics/ColorExtractor.java
index e9d72b7..da5da9c 100644
--- a/src/com/android/launcher3/graphics/ColorExtractor.java
+++ b/src/com/android/launcher3/graphics/ColorExtractor.java
@@ -18,22 +18,32 @@
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.SparseArray;
+import java.util.Arrays;
/**
* Utility class for extracting colors from a bitmap.
*/
public class ColorExtractor {
- public static int findDominantColorByHue(Bitmap bitmap) {
- return findDominantColorByHue(bitmap, 20);
+ private final int NUM_SAMPLES = 20;
+ private final float[] mTmpHsv = new float[3];
+ private final float[] mTmpHueScoreHistogram = new float[360];
+ private final int[] mTmpPixels = new int[NUM_SAMPLES];
+ private final SparseArray<Float> mTmpRgbScores = new SparseArray<>();
+
+ /**
+ * This picks a dominant color, looking for high-saturation, high-value, repeated hues.
+ * @param bitmap The bitmap to scan
+ */
+ public int findDominantColorByHue(Bitmap bitmap) {
+ return findDominantColorByHue(bitmap, NUM_SAMPLES);
}
/**
* This picks a dominant color, looking for high-saturation, high-value, repeated hues.
* @param bitmap The bitmap to scan
- * @param samples The approximate max number of samples to use.
*/
- public static int findDominantColorByHue(Bitmap bitmap, int samples) {
+ public int findDominantColorByHue(Bitmap bitmap, int samples) {
final int height = bitmap.getHeight();
final int width = bitmap.getWidth();
int sampleStride = (int) Math.sqrt((height * width) / samples);
@@ -42,15 +52,18 @@
}
// This is an out-param, for getting the hsv values for an rgb
- float[] hsv = new float[3];
+ float[] hsv = mTmpHsv;
+ Arrays.fill(hsv, 0);
// First get the best hue, by creating a histogram over 360 hue buckets,
// where each pixel contributes a score weighted by saturation, value, and alpha.
- float[] hueScoreHistogram = new float[360];
+ float[] hueScoreHistogram = mTmpHueScoreHistogram;
+ Arrays.fill(hueScoreHistogram, 0);
float highScore = -1;
int bestHue = -1;
- int[] pixels = new int[samples];
+ int[] pixels = mTmpPixels;
+ Arrays.fill(pixels, 0);
int pixelCount = 0;
for (int y = 0; y < height; y += sampleStride) {
@@ -82,7 +95,8 @@
}
}
- SparseArray<Float> rgbScores = new SparseArray<>();
+ SparseArray<Float> rgbScores = mTmpRgbScores;
+ rgbScores.clear();
int bestColor = 0xff000000;
highScore = -1;
// Go back over the RGB colors that match the winning hue,
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 333fe59..0167a1d 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -90,6 +90,7 @@
synchronized (sPoolSync) {
// Clear any temporary state variables
mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;
+ mDisableColorExtractor = false;
next = sPool;
sPool = this;
@@ -105,6 +106,8 @@
private final Context mContext;
private final Canvas mCanvas;
private final PackageManager mPm;
+ private final ColorExtractor mColorExtractor;
+ private boolean mDisableColorExtractor;
private final int mFillResIconDpi;
private final int mIconBitmapSize;
@@ -121,6 +124,7 @@
private LauncherIcons(Context context) {
mContext = context.getApplicationContext();
mPm = mContext.getPackageManager();
+ mColorExtractor = new ColorExtractor();
InvariantDeviceProfile idp = LauncherAppState.getIDP(mContext);
mFillResIconDpi = idp.fillResIconDpi;
@@ -196,7 +200,7 @@
* The bitmap is also visually normalized with other icons.
*/
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user, int iconAppTargetSdk,
- boolean isInstantApp, float [] scale) {
+ boolean isInstantApp, float[] scale) {
if (scale == null) {
scale = new float[1];
}
@@ -223,7 +227,7 @@
} else {
result = bitmap;
}
- return BitmapInfo.fromBitmap(result);
+ return BitmapInfo.fromBitmap(result, mDisableColorExtractor ? null : mColorExtractor);
}
/**
@@ -245,6 +249,14 @@
mWrapperBackgroundColor = (Color.alpha(color) < 255) ? DEFAULT_WRAPPER_BACKGROUND : color;
}
+ /**
+ * Disables the dominant color extraction for all icons loaded through this session (until
+ * this instance is recycled).
+ */
+ public void disableColorExtraction() {
+ mDisableColorExtractor = true;
+ }
+
private Drawable normalizeAndWrapToAdaptiveIcon(Drawable icon, int iconAppTargetSdk,
RectF outIconBounds, float[] outScale) {
float scale = 1f;
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java b/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java
index 4a8bbbd..7529f17 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java
@@ -18,7 +18,6 @@
import static android.app.WallpaperManager.FLAG_SYSTEM;
import static com.android.launcher3.Utilities.getDevicePrefs;
-import static com.android.launcher3.graphics.ColorExtractor.findDominantColorByHue;
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
@@ -47,6 +46,7 @@
import android.util.Pair;
import com.android.launcher3.Utilities;
+import com.android.launcher3.graphics.ColorExtractor;
import java.io.IOException;
import java.util.ArrayList;
@@ -169,6 +169,7 @@
private HandlerThread mWorkerThread;
private Handler mWorkerHandler;
+ private ColorExtractor mColorExtractor;
@Override
public void onCreate() {
@@ -176,6 +177,7 @@
mWorkerThread = new HandlerThread("ColorExtractionService");
mWorkerThread.start();
mWorkerHandler = new Handler(mWorkerThread.getLooper());
+ mColorExtractor = new ColorExtractor();
}
@Override
@@ -258,7 +260,8 @@
String value = VERSION_PREFIX + wallpaperId;
if (bitmap != null) {
- int color = findDominantColorByHue(bitmap, MAX_WALLPAPER_EXTRACTION_AREA);
+ int color = mColorExtractor.findDominantColorByHue(bitmap,
+ MAX_WALLPAPER_EXTRACTION_AREA);
value += "," + color;
}
diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
index 44cdbaf..7f6dd44 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
@@ -124,12 +124,8 @@
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
} else {
// Verify that the widget id is deleted.
- assertTrue(Wait.atMost(new Condition() {
- @Override
- public boolean isTrue() throws Throwable {
- return mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null;
- }
- }, DEFAULT_ACTIVITY_TIMEOUT));
+ assertTrue(Wait.atMost(() -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null,
+ DEFAULT_ACTIVITY_TIMEOUT));
}
}
@@ -143,8 +139,7 @@
/**
* Condition for searching widget id
*/
- private class WidgetSearchCondition extends Condition
- implements Workspace.ItemOperator {
+ private class WidgetSearchCondition implements Condition, Workspace.ItemOperator {
@Override
public boolean isTrue() throws Throwable {
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index 0022d19..ec0a051 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -198,7 +198,7 @@
/**
* Condition for for an item
*/
- private class ItemSearchCondition extends Condition {
+ private class ItemSearchCondition implements Condition {
private final ItemOperator mOp;
diff --git a/tests/src/com/android/launcher3/util/Condition.java b/tests/src/com/android/launcher3/util/Condition.java
index e9ee67c..78c652a 100644
--- a/tests/src/com/android/launcher3/util/Condition.java
+++ b/tests/src/com/android/launcher3/util/Condition.java
@@ -8,47 +8,36 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-public abstract class Condition {
+public interface Condition {
- public abstract boolean isTrue() throws Throwable;
+ boolean isTrue() throws Throwable;
/**
* Converts the condition to be run on UI thread.
*/
- public static Condition runOnUiThread(final Condition condition) {
+ static Condition runOnUiThread(final Condition condition) {
final MainThreadExecutor executor = new MainThreadExecutor();
- return new Condition() {
- @Override
- public boolean isTrue() throws Throwable {
- final AtomicBoolean value = new AtomicBoolean(false);
- final Throwable[] exceptions = new Throwable[1];
- final CountDownLatch latch = new CountDownLatch(1);
- executor.execute(new Runnable() {
- @Override
- public void run() {
- try {
- value.set(condition.isTrue());
- } catch (Throwable e) {
- exceptions[0] = e;
- }
-
- }
- });
- latch.await(1, TimeUnit.SECONDS);
- if (exceptions[0] != null) {
- throw exceptions[0];
+ return () -> {
+ final AtomicBoolean value = new AtomicBoolean(false);
+ final Throwable[] exceptions = new Throwable[1];
+ final CountDownLatch latch = new CountDownLatch(1);
+ executor.execute(() -> {
+ try {
+ value.set(condition.isTrue());
+ } catch (Throwable e) {
+ exceptions[0] = e;
}
- return value.get();
+
+ });
+ latch.await(1, TimeUnit.SECONDS);
+ if (exceptions[0] != null) {
+ throw exceptions[0];
}
+ return value.get();
};
}
- public static Condition minChildCount(final UiObject2 obj, final int childCount) {
- return new Condition() {
- @Override
- public boolean isTrue() {
- return obj.getChildCount() >= childCount;
- }
- };
+ static Condition minChildCount(final UiObject2 obj, final int childCount) {
+ return () -> obj.getChildCount() >= childCount;
}
}