Merge "Add build variant for go-specific recents." into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/TaskListStabilizer.java b/quickstep/src/com/android/quickstep/TaskListStabilizer.java
index 0d23973..3eb26b4 100644
--- a/quickstep/src/com/android/quickstep/TaskListStabilizer.java
+++ b/quickstep/src/com/android/quickstep/TaskListStabilizer.java
@@ -17,79 +17,153 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASK_STABILIZER;
+import android.app.ActivityManager.RecentTaskInfo;
+import android.content.ComponentName;
+import android.os.Process;
import android.os.SystemClock;
-import android.util.SparseArray;
+import android.util.Log;
import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskKey;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
public class TaskListStabilizer {
private static final long TASK_CACHE_TIMEOUT_MS = 5000;
- private final SparseArray<Task> mTempMap = new SparseArray<>();
- private final IntArray mTempArray = new IntArray();
- private final IntSet mTempSet = new IntSet();
+ private static final int INVALID_TASK_ID = -1;
- private final IntArray mLastStableOrder = new IntArray();
- private final IntSet mLastSet = new IntSet();
- private final IntArray mLastUnstableOrder = new IntArray();
+ private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
- private long mLastReorderTime;
+ @Override
+ public void onTaskCreated(int taskId, ComponentName componentName) {
+ onTaskCreatedInternal(taskId);
+ }
- public ArrayList<Task> reorder(ArrayList<Task> tasks) {
+ @Override
+ public void onTaskMovedToFront(int taskId) {
+ onTaskMovedToFrontInternal(taskId);
+ }
+
+ @Override
+ public void onTaskRemoved(int taskId) {
+ onTaskRemovedInternal(taskId);
+ }
+ };
+
+ // Task ids ordered based on recency, 0th index is the latest task
+ private final IntArray mOrderedTaskIds;
+
+ // Wrapper objects used for sorting tasks
+ private final ArrayList<TaskWrapper> mTaskWrappers = new ArrayList<>();
+
+ // Information about recent task re-order which has not been applied yet
+ private int mScheduledMoveTaskId = INVALID_TASK_ID;
+ private long mScheduledMoveTime = 0;
+
+ public TaskListStabilizer() {
+ if (ENABLE_TASK_STABILIZER.get()) {
+ // Initialize the task ids map
+ List<RecentTaskInfo> rawTasks = ActivityManagerWrapper.getInstance().getRecentTasks(
+ Integer.MAX_VALUE, Process.myUserHandle().getIdentifier());
+ mOrderedTaskIds = new IntArray(rawTasks.size());
+ for (RecentTaskInfo info : rawTasks) {
+ mOrderedTaskIds.add(new TaskKey(info).id);
+ }
+
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
+ } else {
+ mOrderedTaskIds = null;
+ }
+ }
+
+ private synchronized void onTaskCreatedInternal(int taskId) {
+ applyScheduledMoveUnchecked();
+ mOrderedTaskIds.add(taskId);
+ }
+
+ private synchronized void onTaskRemovedInternal(int taskId) {
+ applyScheduledMoveUnchecked();
+ mOrderedTaskIds.removeValue(taskId);
+ }
+
+ private void applyScheduledMoveUnchecked() {
+ if (mScheduledMoveTaskId != INVALID_TASK_ID) {
+ // Mode the scheduled task to front
+ mOrderedTaskIds.removeValue(mScheduledMoveTaskId);
+ mOrderedTaskIds.add(mScheduledMoveTaskId);
+ mScheduledMoveTaskId = INVALID_TASK_ID;
+ }
+ }
+
+ /**
+ * Checks if the scheduled move has timed out and moves the task to front accordingly.
+ */
+ private void applyScheduledMoveIfTime() {
+ if (mScheduledMoveTaskId != INVALID_TASK_ID
+ && (SystemClock.uptimeMillis() - mScheduledMoveTime) > TASK_CACHE_TIMEOUT_MS) {
+ applyScheduledMoveUnchecked();
+ }
+ }
+
+ private synchronized void onTaskMovedToFrontInternal(int taskId) {
+ applyScheduledMoveIfTime();
+ mScheduledMoveTaskId = taskId;
+ mScheduledMoveTime = SystemClock.uptimeMillis();
+ }
+
+
+ public synchronized ArrayList<Task> reorder(ArrayList<Task> tasks) {
if (!ENABLE_TASK_STABILIZER.get()) {
return tasks;
}
- // Create task id array
- int count = tasks.size();
- mTempArray.clear();
- mTempSet.clear();
- mTempMap.clear();
+ applyScheduledMoveIfTime();
- for (int i = 0; i < count; i++) {
- Task t = tasks.get(i);
- mTempMap.put(t.key.id, t);
-
- mTempSet.add(t.key.id);
- mTempArray.add(t.key.id);
+ // Ensure that we have enough wrappers
+ int taskCount = tasks.size();
+ for (int i = taskCount - mTaskWrappers.size(); i > 0; i--) {
+ mTaskWrappers.add(new TaskWrapper());
}
- if (mLastSet.equals(mTempSet) && isStabilizationQuickEnough()) {
- if (mLastStableOrder.equals(mTempArray)) {
- // Everything is same
- return tasks;
- }
+ List<TaskWrapper> listToSort = mTaskWrappers.size() == taskCount
+ ? mTaskWrappers : mTaskWrappers.subList(0, taskCount);
+ int missingTaskIndex = -taskCount;
- if (!mLastUnstableOrder.equals(mTempArray)) {
- // Fast reordering, record the current time.
- mLastUnstableOrder.copyFrom(mTempArray);
- mLastReorderTime = SystemClock.uptimeMillis();
- }
+ for (int i = 0; i < taskCount; i++){
+ TaskWrapper wrapper = listToSort.get(i);
+ wrapper.task = tasks.get(i);
+ wrapper.index = mOrderedTaskIds.indexOf(wrapper.task.key.id);
- // Reorder the tasks based on the last stable order.
- ArrayList<Task> sorted = new ArrayList<>(count);
- for (int i = 0; i < count; i++) {
- sorted.add(mTempMap.get(mLastStableOrder.get(i)));
+ // Ensure that missing tasks are put in the front, in the order they appear in the
+ // original list
+ if (wrapper.index < 0) {
+ wrapper.index = missingTaskIndex;
+ missingTaskIndex++;
}
- return sorted;
}
+ Collections.sort(listToSort);
- // Cache the data
- mLastStableOrder.copyFrom(mTempArray);
- mLastUnstableOrder.copyFrom(mTempArray);
- mLastSet.copyFrom(mTempSet);
-
- mLastReorderTime = SystemClock.uptimeMillis();
-
- return tasks;
+ ArrayList<Task> result = new ArrayList<>(taskCount);
+ for (int i = 0; i < taskCount; i++) {
+ result.add(listToSort.get(i).task);
+ }
+ return result;
}
- private boolean isStabilizationQuickEnough() {
- return (SystemClock.uptimeMillis() - mLastReorderTime) < TASK_CACHE_TIMEOUT_MS;
+ private static class TaskWrapper implements Comparable<TaskWrapper> {
+ Task task;
+ int index;
+
+ @Override
+ public int compareTo(TaskWrapper other) {
+ return Integer.compare(index, other.index);
+ }
}
}
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 8c4dd1e..53877ff 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -33,9 +33,11 @@
<attr name="workspaceKeyShadowColor" format="color" />
<attr name="workspaceStatusBarScrim" format="reference" />
<attr name="widgetsTheme" format="reference" />
- <attr name="folderDotColor" format="color" />
<attr name="loadingIconColor" format="color" />
+ <attr name="folderDotColor" format="color" />
+ <attr name="folderIconRadius" format="float" />
+
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="BubbleTextView">
<attr name="layoutHorizontal" format="boolean" />
diff --git a/res/xml/folder_shapes.xml b/res/xml/folder_shapes.xml
new file mode 100644
index 0000000..e60d333
--- /dev/null
+++ b/res/xml/folder_shapes.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shapes xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+ <Circle launcher:folderIconRadius="1" />
+
+ <!-- Default icon for AOSP -->
+ <RoundedSquare launcher:folderIconRadius="0.16" />
+
+ <!-- Rounded icon from RRO -->
+ <RoundedSquare launcher:folderIconRadius="0.6" />
+
+ <!-- Square icon -->
+ <RoundedSquare launcher:folderIconRadius="0" />
+
+ <TearDrop launcher:folderIconRadius="0.3" />
+ <Squircle launcher:folderIconRadius="0.2" />
+
+</shapes>
\ No newline at end of file
diff --git a/src/com/android/launcher3/MainProcessInitializer.java b/src/com/android/launcher3/MainProcessInitializer.java
index 9692d73..93df025 100644
--- a/src/com/android/launcher3/MainProcessInitializer.java
+++ b/src/com/android/launcher3/MainProcessInitializer.java
@@ -38,6 +38,6 @@
FileLog.setDir(context.getApplicationContext().getFilesDir());
FeatureFlags.initialize(context);
SessionCommitReceiver.applyDefaultUserPrefs(context);
- FolderShape.init();
+ FolderShape.init(context);
}
}
diff --git a/src/com/android/launcher3/folder/FolderShape.java b/src/com/android/launcher3/folder/FolderShape.java
index ae279cb..f7cdb77 100644
--- a/src/com/android/launcher3/folder/FolderShape.java
+++ b/src/com/android/launcher3/folder/FolderShape.java
@@ -23,6 +23,9 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -34,13 +37,28 @@
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.util.Xml;
import android.view.ViewOutlineProvider;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.util.Themes;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.annotation.Nullable;
/**
* Abstract representation of the shape of a folder icon
@@ -53,15 +71,7 @@
return sInstance;
}
- private static FolderShape[] getAllShapes() {
- return new FolderShape[] {
- new Circle(),
- new RoundedSquare(8f / 50), // Ratios based on path defined in config_icon_mask
- new RoundedSquare(30f / 50),
- new Square(),
- new TearDrop(),
- new Squircle()};
- }
+ private SparseArray<TypedValue> mAttrs;
public abstract void drawShape(Canvas canvas, float offsetX, float offsetY, float radius,
Paint paint);
@@ -71,6 +81,11 @@
public abstract Animator createRevealAnimator(Folder target, Rect startRect, Rect endRect,
float endRadius, boolean isReversed);
+ @Nullable
+ public TypedValue getAttrValue(int attr) {
+ return mAttrs == null ? null : mAttrs.get(attr);
+ }
+
/**
* Abstract shape where the reveal animation is a derivative of a round rect animation
*/
@@ -163,44 +178,22 @@
}
}
- public static class Square extends SimpleRectShape {
-
- @Override
- public void drawShape(Canvas canvas, float offsetX, float offsetY, float radius, Paint p) {
- float cx = radius + offsetX;
- float cy = radius + offsetY;
- canvas.drawRect(cx - radius, cy - radius, cx + radius, cy + radius, p);
- }
-
- @Override
- public void addShape(Path path, float offsetX, float offsetY, float radius) {
- float cx = radius + offsetX;
- float cy = radius + offsetY;
- path.addRect(cx - radius, cy - radius, cx + radius, cy + radius, Path.Direction.CW);
- }
-
- @Override
- protected float getStartRadius(Rect startRect) {
- return 0;
- }
- }
-
public static class RoundedSquare extends SimpleRectShape {
/**
- * Ratio of corner radius to half size. Based on the
+ * Ratio of corner radius to half size.
*/
- private final float mRadiusFactor;
+ private final float mRadiusRatio;
- public RoundedSquare(float radiusFactor) {
- mRadiusFactor = radiusFactor;
+ public RoundedSquare(float radiusRatio) {
+ mRadiusRatio = radiusRatio;
}
@Override
public void drawShape(Canvas canvas, float offsetX, float offsetY, float radius, Paint p) {
float cx = radius + offsetX;
float cy = radius + offsetY;
- float cr = radius * mRadiusFactor;
+ float cr = radius * mRadiusRatio;
canvas.drawRoundRect(cx - radius, cy - radius, cx + radius, cy + radius, cr, cr, p);
}
@@ -208,14 +201,14 @@
public void addShape(Path path, float offsetX, float offsetY, float radius) {
float cx = radius + offsetX;
float cy = radius + offsetY;
- float cr = radius * mRadiusFactor;
+ float cr = radius * mRadiusRatio;
path.addRoundRect(cx - radius, cy - radius, cx + radius, cy + radius, cr, cr,
Path.Direction.CW);
}
@Override
protected float getStartRadius(Rect startRect) {
- return (startRect.width() / 2f) * mRadiusFactor;
+ return (startRect.width() / 2f) * mRadiusRatio;
}
}
@@ -224,13 +217,16 @@
/**
* Radio of short radius to large radius, based on the shape options defined in the config.
*/
- private static final float RADIUS_RATIO = 15f / 50;
-
+ private final float mRadiusRatio;
private final float[] mTempRadii = new float[8];
+ public TearDrop(float radiusRatio) {
+ mRadiusRatio = radiusRatio;
+ }
+
@Override
public void addShape(Path p, float offsetX, float offsetY, float r1) {
- float r2 = r1 * RADIUS_RATIO;
+ float r2 = r1 * mRadiusRatio;
float cx = r1 + offsetX;
float cy = r1 + offsetY;
@@ -249,7 +245,7 @@
protected AnimatorUpdateListener newUpdateListener(Rect startRect, Rect endRect,
float endRadius, Path outPath) {
float r1 = startRect.width() / 2f;
- float r2 = r1 * RADIUS_RATIO;
+ float r2 = r1 * mRadiusRatio;
float[] startValues = new float[] {
startRect.left, startRect.top, startRect.right, startRect.bottom, r1, r2};
@@ -273,13 +269,17 @@
/**
* Radio of radius to circle radius, based on the shape options defined in the config.
*/
- private static final float RADIUS_RATIO = 10f / 50;
+ private final float mRadiusRatio;
+
+ public Squircle(float radiusRatio) {
+ mRadiusRatio = radiusRatio;
+ }
@Override
public void addShape(Path p, float offsetX, float offsetY, float r) {
float cx = r + offsetX;
float cy = r + offsetY;
- float control = r - r * RADIUS_RATIO;
+ float control = r - r * mRadiusRatio;
p.moveTo(cx, cy - r);
addLeftCurve(cx, cy, r, control, p);
@@ -310,7 +310,7 @@
float startCX = startRect.exactCenterX();
float startCY = startRect.exactCenterY();
float startR = startRect.width() / 2f;
- float startControl = startR - startR * RADIUS_RATIO;
+ float startControl = startR - startR * mRadiusRatio;
float startHShift = 0;
float startVShift = 0;
@@ -351,17 +351,63 @@
}
/**
- * Initializes the shape which is closest to closest to the {@link AdaptiveIconDrawable}
+ * Initializes the shape which is closest to the {@link AdaptiveIconDrawable}
*/
- public static void init() {
+ public static void init(Context context) {
if (!Utilities.ATLEAST_OREO) {
return;
}
- new MainThreadExecutor().execute(FolderShape::pickShapeInBackground);
+ new MainThreadExecutor().execute(() -> pickShapeInBackground(context));
+ }
+
+ private static FolderShape getShapeDefinition(String type, float radius) {
+ switch (type) {
+ case "Circle":
+ return new Circle();
+ case "RoundedSquare":
+ return new RoundedSquare(radius);
+ case "TearDrop":
+ return new TearDrop(radius);
+ case "Squircle":
+ return new Squircle(radius);
+ default:
+ throw new IllegalArgumentException("Invalid shape type: " + type);
+ }
+ }
+
+ private static List<FolderShape> getAllShapes(Context context) {
+ ArrayList<FolderShape> result = new ArrayList<>();
+ try (XmlResourceParser parser = context.getResources().getXml(R.xml.folder_shapes)) {
+
+ // Find the root tag
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_TAG
+ && type != XmlPullParser.END_DOCUMENT
+ && !"shapes".equals(parser.getName()));
+
+ final int depth = parser.getDepth();
+ int[] radiusAttr = new int[] {R.attr.folderIconRadius};
+ while (((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+
+ if (type == XmlPullParser.START_TAG) {
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+ TypedArray a = context.obtainStyledAttributes(attrs, radiusAttr);
+ FolderShape shape = getShapeDefinition(parser.getName(), a.getFloat(0, 1));
+ a.recycle();
+
+ shape.mAttrs = Themes.createValueMap(context, attrs);
+ result.add(shape);
+ }
+ }
+ } catch (IOException | XmlPullParserException e) {
+ throw new RuntimeException(e);
+ }
+ return result;
}
@TargetApi(Build.VERSION_CODES.O)
- protected static void pickShapeInBackground() {
+ protected static void pickShapeInBackground(Context context) {
// Pick any large size
int size = 200;
@@ -379,7 +425,7 @@
// Find the shape with minimum area of divergent region.
int minArea = Integer.MAX_VALUE;
FolderShape closestShape = null;
- for (FolderShape shape : getAllShapes()) {
+ for (FolderShape shape : getAllShapes(context)) {
shapePath.reset();
shape.addShape(shapePath, 0, 0, size / 2f);
shapeR.setPath(shapePath, full);
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 5fc5551..0d55301 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -62,7 +62,7 @@
final IntArray addedWorkspaceScreensFinal = new IntArray();
synchronized(dataModel) {
- IntArray workspaceScreens = dataModel.workspaceScreens.clone();
+ IntArray workspaceScreens = dataModel.collectWorkspaceScreens();
List<ItemInfo> filteredItems = new ArrayList<>();
for (Pair<ItemInfo, Object> entry : mItemList) {
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index f6e220f..23c6faf 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -92,7 +92,7 @@
synchronized (mBgDataModel) {
workspaceItems.addAll(mBgDataModel.workspaceItems);
appWidgets.addAll(mBgDataModel.appWidgets);
- orderedScreenIds.addAll(mBgDataModel.workspaceScreens);
+ orderedScreenIds.addAll(mBgDataModel.collectWorkspaceScreens());
mBgDataModel.lastBindId++;
}
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 151d6f4..b338fff 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -27,6 +27,7 @@
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.DumpTargetWrapper;
import com.android.launcher3.model.nano.LauncherDumpProto;
@@ -37,6 +38,7 @@
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.IntSparseArrayMap;
import com.google.protobuf.nano.MessageNano;
@@ -81,11 +83,6 @@
public final IntSparseArrayMap<FolderInfo> folders = new IntSparseArrayMap<>();
/**
- * Ordered list of workspace screens ids.
- */
- public final IntArray workspaceScreens = new IntArray();
-
- /**
* Map of ShortcutKey to the number of times it is pinned.
*/
public final Map<ShortcutKey, MutableInt> pinnedShortcutCounts = new HashMap<>();
@@ -118,11 +115,26 @@
appWidgets.clear();
folders.clear();
itemsIdMap.clear();
- workspaceScreens.clear();
pinnedShortcutCounts.clear();
deepShortcutMap.clear();
}
+ /**
+ * Creates an array of valid workspace screens based on current items in the model.
+ */
+ public synchronized IntArray collectWorkspaceScreens() {
+ IntSet screenSet = new IntSet();
+ for (ItemInfo item: itemsIdMap) {
+ if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+ screenSet.add(item.screenId);
+ }
+ }
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN.get() || screenSet.isEmpty()) {
+ screenSet.add(Workspace.FIRST_SCREEN_ID);
+ }
+ return screenSet.getArray();
+ }
+
public synchronized void dump(String prefix, FileDescriptor fd, PrintWriter writer,
String[] args) {
if (Arrays.asList(args).contains("--proto")) {
@@ -130,11 +142,6 @@
return;
}
writer.println(prefix + "Data Model:");
- writer.print(prefix + " ---- workspace screens: ");
- for (int i = 0; i < workspaceScreens.size(); i++) {
- writer.print(" " + workspaceScreens.get(i));
- }
- writer.println();
writer.println(prefix + " ---- workspace items ");
for (int i = 0; i < workspaceItems.size(); i++) {
writer.println(prefix + '\t' + workspaceItems.get(i).toString());
@@ -167,6 +174,7 @@
// Add top parent nodes. (L1)
DumpTargetWrapper hotseat = new DumpTargetWrapper(ContainerType.HOTSEAT, 0);
IntSparseArrayMap<DumpTargetWrapper> workspaces = new IntSparseArrayMap<>();
+ IntArray workspaceScreens = collectWorkspaceScreens();
for (int i = 0; i < workspaceScreens.size(); i++) {
workspaces.put(workspaceScreens.get(i),
new DumpTargetWrapper(ContainerType.WORKSPACE, i));
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 8a6aa1af..cfabc10 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -31,7 +31,6 @@
import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
-import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
@@ -43,19 +42,17 @@
import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
-import com.android.launcher3.ItemInfoWithIcon;
-import com.android.launcher3.icons.ComponentWithLabel;
-import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
-import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
-import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
@@ -63,16 +60,18 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIconPreviewVerifier;
+import com.android.launcher3.icons.ComponentWithLabel;
+import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
+import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.LauncherActivtiyCachingLogic;
import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.provider.ImportDataTask;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.LooperIdleLock;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
@@ -158,9 +157,9 @@
allItems.addAll(mBgDataModel.workspaceItems);
allItems.addAll(mBgDataModel.appWidgets);
}
- int firstScreen = mBgDataModel.workspaceScreens.isEmpty()
- ? -1 // In this case, we can still look at the items in the hotseat.
- : mBgDataModel.workspaceScreens.get(0);
+ // Screen set is never empty
+ final int firstScreen = mBgDataModel.collectWorkspaceScreens().get(0);
+
filterCurrentWorkspaceItems(firstScreen, allItems, firstScreenItems,
new ArrayList<>() /* otherScreenItems are ignored */);
mFirstScreenBroadcast.sendBroadcasts(mApp.getContext(), firstScreenItems);
@@ -784,16 +783,6 @@
null,
new Handler(LauncherModel.getWorkerLooper()));
}
-
- // Initialize the screens array. Using an InstSet ensures that the screen ids
- // are sorted.
- IntSet screenSet = new IntSet();
- for (ItemInfo item: mBgDataModel.itemsIdMap) {
- if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- screenSet.add(item.screenId);
- }
- }
- mBgDataModel.workspaceScreens.addAll(screenSet.getArray());
}
}
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index 5f965a3..e3ab1a5 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -21,6 +21,9 @@
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.util.TypedValue;
/**
* Various utility methods associated with theming.
@@ -104,4 +107,26 @@
target.getArray()[14] = Color.blue(dstColor) - Color.blue(srcColor);
target.getArray()[19] = Color.alpha(dstColor) - Color.alpha(srcColor);
}
+
+ /**
+ * Creates a map for attribute-name to value for all the values in {@param attrs} which can be
+ * held in memory for later use.
+ */
+ public static SparseArray<TypedValue> createValueMap(Context context, AttributeSet attrSet) {
+ int count = attrSet.getAttributeCount();
+ int[] attrNames = new int[count];
+ for (int i = 0; i < count; i++) {
+ attrNames[i] = attrSet.getAttributeNameResource(i);
+ }
+
+ SparseArray<TypedValue> result = new SparseArray<>(count);
+ TypedArray ta = context.obtainStyledAttributes(attrSet, attrNames);
+ for (int i = 0; i < count; i++) {
+ TypedValue tv = new TypedValue();
+ ta.getValue(i, tv);
+ result.put(attrNames[i], tv);
+ }
+
+ return result;
+ }
}