Merge "DO NOT MERGE Fixing some regressions" into lmp-dev
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 8a80b76..e7ac2e1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -32,7 +32,7 @@
// Enables the filtering of tasks according to their grouping
public static final boolean EnableTaskFiltering = false;
// Enables clipping of tasks against each other
- public static final boolean EnableTaskStackClipping = true;
+ public static final boolean EnableTaskStackClipping = false;
// Enables tapping on the TaskBar to launch the task
public static final boolean EnableTaskBarTouchEvents = true;
// Enables app-info pane on long-pressing the icon
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 56de0be..1e581c1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -458,8 +458,6 @@
filter.addAction(ACTION_TOGGLE_RECENTS_ACTIVITY);
filter.addAction(ACTION_START_ENTER_ANIMATION);
registerReceiver(mServiceBroadcastReceiver, filter);
-
- mVisible = true;
}
@Override
@@ -485,6 +483,8 @@
}
}, 1);
}
+
+ mVisible = true;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
index 31825af..4c0ff48 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
@@ -72,7 +72,12 @@
/** Adds a runnable to the last-decrement runnables list. */
public void addLastDecrementRunnable(Runnable r) {
+ // To ensure that the last decrement always calls, we increment and decrement after setting
+ // the last decrement runnable
+ boolean ensureLastDecrement = (mCount == 0);
+ if (ensureLastDecrement) increment();
mLastDecRunnables.add(r);
+ if (ensureLastDecrement) decrement();
}
/** Decrements the ref count */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index bda195b..607e155 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -16,16 +16,10 @@
package com.android.systemui.recents.misc;
-import android.app.ActivityManager;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.ParcelFileDescriptor;
import com.android.systemui.recents.RecentsConfiguration;
-import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -73,22 +67,25 @@
}
}
- /** Calculates the luminance-preserved greyscale of a given color. */
- public static int colorToGreyscale(int color) {
- return Math.round(0.2126f * Color.red(color) + 0.7152f * Color.green(color) +
- 0.0722f * Color.blue(color));
- }
+ /** Calculates the constrast between two colors, using the algorithm provided by the WCAG v2. */
+ public static float computeContrastBetweenColors(int bg, int fg) {
+ float bgR = Color.red(bg) / 255f;
+ float bgG = Color.green(bg) / 255f;
+ float bgB = Color.blue(bg) / 255f;
+ bgR = (bgR < 0.03928f) ? bgR / 12.92f : (float) Math.pow((bgR + 0.055f) / 1.055f, 2.4f);
+ bgG = (bgG < 0.03928f) ? bgG / 12.92f : (float) Math.pow((bgG + 0.055f) / 1.055f, 2.4f);
+ bgB = (bgB < 0.03928f) ? bgB / 12.92f : (float) Math.pow((bgB + 0.055f) / 1.055f, 2.4f);
+ float bgL = 0.2126f * bgR + 0.7152f * bgG + 0.0722f * bgB;
+
+ float fgR = Color.red(fg) / 255f;
+ float fgG = Color.green(fg) / 255f;
+ float fgB = Color.blue(fg) / 255f;
+ fgR = (fgR < 0.03928f) ? fgR / 12.92f : (float) Math.pow((fgR + 0.055f) / 1.055f, 2.4f);
+ fgG = (fgG < 0.03928f) ? fgG / 12.92f : (float) Math.pow((fgG + 0.055f) / 1.055f, 2.4f);
+ fgB = (fgB < 0.03928f) ? fgB / 12.92f : (float) Math.pow((fgB + 0.055f) / 1.055f, 2.4f);
+ float fgL = 0.2126f * fgR + 0.7152f * fgG + 0.0722f * fgB;
- /** Returns the ideal color to draw on top of a specified background color. */
- public static int getIdealColorForBackgroundColorGreyscale(int greyscale, int lightRes,
- int darkRes) {
- return (greyscale < 128) ? lightRes : darkRes;
- }
- /** Returns the ideal drawable to draw on top of a specified background color. */
- public static Drawable getIdealResourceForBackgroundColorGreyscale(int greyscale,
- Drawable lightRes,
- Drawable darkRes) {
- return (greyscale < 128) ? lightRes : darkRes;
+ return Math.abs((fgL + 0.05f) / (bgL + 0.05f));
}
/** Sets some private shadow properties. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java
index 1344729..757c07f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java
@@ -29,6 +29,6 @@
@Override
protected int computeSize(Bitmap b) {
// The cache size will be measured in kilobytes rather than number of items
- return b.getAllocationByteCount() / 1024;
+ return b.getAllocationByteCount();
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java
index 61d19da..5b50358 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java
@@ -31,6 +31,6 @@
// The cache size will be measured in kilobytes rather than number of items
// NOTE: this isn't actually correct, as the icon may be smaller
int maxBytes = (d.getIntrinsicWidth() * d.getIntrinsicHeight() * 4);
- return maxBytes / 1024;
+ return maxBytes;
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
index 3ccca9a..5f4fabe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
@@ -73,11 +73,6 @@
return mCache.get(key);
}
- /** Gets the previous task key that matches the specified key. */
- final Task.TaskKey getKey(Task.TaskKey key) {
- return mKeys.get(key);
- }
-
/** Puts an entry in the cache for a specific key. */
final void put(Task.TaskKey key, V value) {
mCache.put(key, value);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
index 2d50659..2f1c1c4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
@@ -45,7 +45,7 @@
mSystemServicesProxy = new SystemServicesProxy(context);
mCb = cb;
try {
- register(context, Looper.getMainLooper(), false);
+ register(context, Looper.getMainLooper(), true);
} catch (IllegalStateException e) {
e.printStackTrace();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 854ea1c..cbb8892 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -27,38 +27,29 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.UserHandle;
-import android.util.Pair;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.SystemServicesProxy;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
/** A bitmap load queue */
class TaskResourceLoadQueue {
ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<Task>();
- ConcurrentHashMap<Task.TaskKey, Boolean> mForceLoadSet =
- new ConcurrentHashMap<Task.TaskKey, Boolean>();
-
- static final Boolean sFalse = new Boolean(false);
/** Adds a new task to the load queue */
- void addTask(Task t, boolean forceLoad) {
+ void addTask(Task t) {
if (Console.Enabled) {
Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|addTask]");
}
if (!mQueue.contains(t)) {
mQueue.add(t);
}
- if (forceLoad) {
- mForceLoadSet.put(t.key, new Boolean(true));
- }
synchronized(this) {
notifyAll();
}
@@ -68,19 +59,11 @@
* Retrieves the next task from the load queue, as well as whether we want that task to be
* force reloaded.
*/
- Pair<Task, Boolean> nextTask() {
+ Task nextTask() {
if (Console.Enabled) {
Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|nextTask]");
}
- Task task = mQueue.poll();
- Boolean forceLoadTask = null;
- if (task != null) {
- forceLoadTask = mForceLoadSet.remove(task.key);
- }
- if (forceLoadTask == null) {
- forceLoadTask = sFalse;
- }
- return new Pair<Task, Boolean>(task, forceLoadTask);
+ return mQueue.poll();
}
/** Removes a task from the load queue */
@@ -89,7 +72,6 @@
Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|removeTask]");
}
mQueue.remove(t);
- mForceLoadSet.remove(t.key);
}
/** Clears all the tasks from the load queue */
@@ -98,7 +80,6 @@
Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|clearTasks]");
}
mQueue.clear();
- mForceLoadSet.clear();
}
/** Returns whether the load queue is empty */
@@ -119,19 +100,20 @@
DrawableLruCache mApplicationIconCache;
BitmapLruCache mThumbnailCache;
Bitmap mDefaultThumbnail;
+ BitmapDrawable mDefaultApplicationIcon;
boolean mCancelled;
boolean mWaitingOnLoadQueue;
/** Constructor, creates a new loading thread that loads task resources in the background */
- public TaskResourceLoader(TaskResourceLoadQueue loadQueue,
- DrawableLruCache applicationIconCache,
- BitmapLruCache thumbnailCache,
- Bitmap defaultThumbnail) {
+ public TaskResourceLoader(TaskResourceLoadQueue loadQueue, DrawableLruCache applicationIconCache,
+ BitmapLruCache thumbnailCache, Bitmap defaultThumbnail,
+ BitmapDrawable defaultApplicationIcon) {
mLoadQueue = loadQueue;
mApplicationIconCache = applicationIconCache;
mThumbnailCache = thumbnailCache;
mDefaultThumbnail = defaultThumbnail;
+ mDefaultApplicationIcon = defaultApplicationIcon;
mMainThreadHandler = new Handler();
mLoadThread = new HandlerThread("Recents-TaskResourceLoader");
mLoadThread.setPriority(Thread.NORM_PRIORITY - 1);
@@ -200,59 +182,51 @@
SystemServicesProxy ssp = mSystemServicesProxy;
// Load the next item from the queue
- Pair<Task, Boolean> nextTaskData = mLoadQueue.nextTask();
- final Task t = nextTaskData.first;
- final boolean forceLoadTask = nextTaskData.second;
+ final Task t = mLoadQueue.nextTask();
if (t != null) {
- Drawable loadIcon = mApplicationIconCache.getCheckLastActiveTime(t.key);
- Bitmap loadThumbnail = mThumbnailCache.getCheckLastActiveTime(t.key);
+ Drawable cachedIcon = mApplicationIconCache.getCheckLastActiveTime(t.key);
+ Bitmap cachedThumbnail = mThumbnailCache.getCheckLastActiveTime(t.key);
if (Console.Enabled) {
Console.log(Constants.Log.App.TaskDataLoader,
" [TaskResourceLoader|load]",
- t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail +
- " forceLoad: " + forceLoadTask);
+ t + " icon: " + cachedIcon + " thumbnail: " + cachedThumbnail);
}
- // Load the application icon
- if (loadIcon == null || forceLoadTask) {
+ // Load the application icon if it is stale or we haven't cached one yet
+ if (cachedIcon == null) {
+ Drawable icon = null;
ActivityInfo info = ssp.getActivityInfo(t.key.baseIntent.getComponent(),
t.userId);
- Drawable icon = ssp.getActivityIcon(info, t.userId);
- if (!mCancelled) {
- if (icon != null) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- " [TaskResourceLoader|loadIcon]", icon);
- }
- loadIcon = icon;
- mApplicationIconCache.put(t.key, icon);
+ if (info != null) {
+ icon = ssp.getActivityIcon(info, t.userId);
+ if (Console.Enabled) {
+ Console.log(Constants.Log.App.TaskDataLoader,
+ " [TaskResourceLoader|loadedIcon]", icon);
}
}
+ // If we can't load the icon, then set the default application icon into the
+ // cache. This will remain until the task's last active time is updated.
+ cachedIcon = icon != null ? icon : mDefaultApplicationIcon;
+ mApplicationIconCache.put(t.key, cachedIcon);
}
- // Load the thumbnail
- if (loadThumbnail == null || forceLoadTask) {
+ // Load the thumbnail if it is stale or we haven't cached one yet
+ if (cachedThumbnail == null) {
Bitmap thumbnail = ssp.getTaskThumbnail(t.key.id);
- if (!mCancelled) {
- if (thumbnail != null) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- " [TaskResourceLoader|loadThumbnail]", thumbnail);
- }
- thumbnail.setHasAlpha(false);
- loadThumbnail = thumbnail;
- } else {
- loadThumbnail = mDefaultThumbnail;
- Console.logError(mContext,
- "Failed to load task top thumbnail for: " +
- t.key.baseIntent.getComponent().getPackageName());
+ if (thumbnail != null) {
+ thumbnail.setHasAlpha(false);
+ if (Console.Enabled) {
+ Console.log(Constants.Log.App.TaskDataLoader,
+ " [TaskResourceLoader|loadedThumbnail]", thumbnail);
}
- // We put the default thumbnail in the cache anyways
- mThumbnailCache.put(t.key, loadThumbnail);
}
+ // Even if we can't load the icon, we set the default thumbnail into the
+ // cache. This will remain until the task's last active time is updated.
+ cachedThumbnail = thumbnail != null ? thumbnail : mDefaultThumbnail;
+ mThumbnailCache.put(t.key, cachedThumbnail);
}
if (!mCancelled) {
// Notify that the task data has changed
- final Drawable newIcon = loadIcon;
- final Bitmap newThumbnail = loadThumbnail;
+ final Drawable newIcon = cachedIcon;
+ final Bitmap newThumbnail = cachedThumbnail;
mMainThreadHandler.post(new Runnable() {
@Override
public void run() {
@@ -306,11 +280,11 @@
/** Private Constructor */
private RecentsTaskLoader(Context context) {
// Calculate the cache sizes, we just use a reasonable number here similar to those
- // suggested in the Android docs, 1/8th for the thumbnail cache and 1/32 of the max memory
+ // suggested in the Android docs, 1/6th for the thumbnail cache and 1/30 of the max memory
// for icons.
- int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
- mMaxThumbnailCacheSize = maxMemory / 8;
- mMaxIconCacheSize = mMaxThumbnailCacheSize / 4;
+ int maxMemory = (int) Runtime.getRuntime().maxMemory();
+ mMaxThumbnailCacheSize = maxMemory / 6;
+ mMaxIconCacheSize = mMaxThumbnailCacheSize / 5;
int iconCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
mMaxIconCacheSize;
int thumbnailCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
@@ -340,7 +314,7 @@
mApplicationIconCache = new DrawableLruCache(iconCacheSize);
mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
mLoader = new TaskResourceLoader(mLoadQueue, mApplicationIconCache, mThumbnailCache,
- mDefaultThumbnail);
+ mDefaultThumbnail, mDefaultApplicationIcon);
if (Console.Enabled) {
Console.log(Constants.Log.App.TaskDataLoader,
@@ -394,7 +368,7 @@
}
RecentsConfiguration config = RecentsConfiguration.getInstance();
Resources res = context.getResources();
- ArrayList<Task> tasksToForceLoad = new ArrayList<Task>();
+ LinkedHashSet<Task> tasksToLoad = new LinkedHashSet<Task>();
TaskStack stack = new TaskStack();
SpaceNode root = new SpaceNode();
root.setStack(stack);
@@ -446,15 +420,16 @@
if (isForemostTask) {
// We force loading the application icon for the foremost task
task.applicationIcon = ssp.getActivityIcon(info, task.userId);
- if (task.applicationIcon != null) {
- mApplicationIconCache.put(task.key, task.applicationIcon);
- } else {
+ if (task.applicationIcon == null) {
task.applicationIcon = mDefaultApplicationIcon;
}
+ // Even if we can't load the icon we set the default application icon into
+ // the cache. This will remain until the task's last active time is updated.
+ mApplicationIconCache.put(task.key, task.applicationIcon);
} else {
- // Either the task has updated, or we haven't cached any information for the
- // task, so reload it
- tasksToForceLoad.add(task);
+ // Either the task has changed since the last active time, or it was not
+ // previously cached, so try and load the task anew.
+ tasksToLoad.add(task);
}
}
@@ -473,11 +448,13 @@
} else {
task.thumbnail = mDefaultThumbnail;
}
+ // Even if we can't load the thumbnail we set the default thumbnail into
+ // the cache. This will remain until the task's last active time is updated.
mThumbnailCache.put(task.key, task.thumbnail);
} else {
- // Either the task has updated, or we haven't cached any information for the
- // task, so reload it
- tasksToForceLoad.add(task);
+ // Either the task has changed since the last active time, or it was not
+ // previously cached, so try and load the task anew.
+ tasksToLoad.add(task);
}
}
}
@@ -496,14 +473,14 @@
}
// Simulate the groupings that we describe
- stack.createSimulatedAffiliatedGroupings();
+ stack.createAffiliatedGroupings();
// Start the task loader
mLoader.start(context);
- // Add all the tasks that we are force/re-loading
- for (Task t : tasksToForceLoad) {
- mLoadQueue.addTask(t, true);
+ // Add all the tasks that we are reloading
+ for (Task t : tasksToLoad) {
+ mLoadQueue.addTask(t);
}
// Update the package monitor with the list of packages to listen for
@@ -526,7 +503,7 @@
stack.addTask(new Task(t.persistentId, true, t.baseIntent, t.affiliatedTaskId, null,
null, 0, 0, t.firstActiveTime, t.lastActiveTime, (i == (taskCount - 1))));
}
- stack.createSimulatedAffiliatedGroupings();
+ stack.createAffiliatedGroupings();
return stack;
}
@@ -551,7 +528,7 @@
requiresLoad = true;
}
if (requiresLoad) {
- mLoadQueue.addTask(t, false);
+ mLoadQueue.addTask(t);
}
t.notifyTaskDataLoaded(thumbnail, applicationIcon);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 88e9f40..1670735 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -18,6 +18,7 @@
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import com.android.systemui.recents.misc.Utilities;
@@ -84,7 +85,7 @@
public Drawable activityIcon;
public String activityLabel;
public int colorPrimary;
- public int colorPrimaryGreyscale;
+ public boolean useLightOnPrimaryColor;
public Bitmap thumbnail;
public boolean isActive;
public boolean canLockToTask;
@@ -104,7 +105,8 @@
this.activityLabel = activityTitle;
this.activityIcon = activityIcon;
this.colorPrimary = colorPrimary;
- this.colorPrimaryGreyscale = Utilities.colorToGreyscale(colorPrimary);
+ this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(colorPrimary,
+ Color.WHITE) > 3f;
this.isActive = isActive;
this.canLockToTask = canLockToTask;
this.userId = userId;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 7dd15a6..e3bcff0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -320,7 +320,7 @@
/**
* Temporary: This method will simulate affiliation groups by
*/
- public void createSimulatedAffiliatedGroupings() {
+ public void createAffiliatedGroupings() {
if (Constants.DebugFlags.App.EnableSimulatedTaskGroups) {
HashMap<Task.TaskKey, Task> taskMap = new HashMap<Task.TaskKey, Task>();
// Sort all tasks by increasing firstActiveTime of the task
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 99b012e..73bbf86 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -191,10 +191,6 @@
/** Requests all task stacks to start their enter-recents animation */
public void startEnterRecentsAnimation(ViewAnimation.TaskViewEnterContext ctx) {
- // Handle the case when there are no views by incrementing and decrementing after all
- // animations are started.
- ctx.postAnimationTrigger.increment();
-
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -203,18 +199,10 @@
stackView.startEnterRecentsAnimation(ctx);
}
}
-
- // Handle the case when there are no views by incrementing and decrementing after all
- // animations are started.
- ctx.postAnimationTrigger.decrement();
}
/** Requests all task stacks to start their exit-recents animation */
public void startExitToHomeAnimation(ViewAnimation.TaskViewExitContext ctx) {
- // Handle the case when there are no views by incrementing and decrementing after all
- // animations are started.
- ctx.postAnimationTrigger.increment();
-
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -224,10 +212,6 @@
}
}
- // Handle the case when there are no views by incrementing and decrementing after all
- // animations are started.
- ctx.postAnimationTrigger.decrement();
-
// Notify of the exit animation
mCb.onExitToHomeAnimationTriggered();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
index db84962..deb9df3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
@@ -162,11 +162,10 @@
}
// Try and apply the system ui tint
setBackgroundColor(t.colorPrimary);
- mActivityDescription.setTextColor(Utilities.getIdealColorForBackgroundColorGreyscale(
- t.colorPrimaryGreyscale, mConfig.taskBarViewLightTextColor,
- mConfig.taskBarViewDarkTextColor));
- mDismissButton.setImageDrawable(Utilities.getIdealResourceForBackgroundColorGreyscale(
- t.colorPrimaryGreyscale, mLightDismissDrawable, mDarkDismissDrawable));
+ mActivityDescription.setTextColor(t.useLightOnPrimaryColor ?
+ mConfig.taskBarViewLightTextColor : mConfig.taskBarViewDarkTextColor);
+ mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
+ mLightDismissDrawable : mDarkDismissDrawable);
}
/** Unbinds the bar view from the task */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 599c590..adc808a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -302,7 +302,6 @@
int[] visibleRange = mTmpVisibleRange;
updateStackTransforms(mCurrentTaskTransforms, tasks, stackScroll, visibleRange, false);
TaskViewTransform tmpTransform = new TaskViewTransform();
- TaskStack.GroupTaskIndex gti = new TaskStack.GroupTaskIndex();
// Return all the invisible children to the pool
HashMap<Task, TaskView> taskChildViewMap = getTaskChildViewMap();
@@ -355,6 +354,47 @@
}
}
+ /** Updates the clip for each of the task views. */
+ void clipTaskViews() {
+ // Update the clip on each task child
+ if (Constants.DebugFlags.App.EnableTaskStackClipping) {
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount - 1; i++) {
+ TaskView tv = (TaskView) getChildAt(i);
+ TaskView nextTv = null;
+ TaskView tmpTv = null;
+ int clipBottom = 0;
+ if (tv.shouldClipViewInStack()) {
+ // Find the next view to clip against
+ int nextIndex = i;
+ while (nextIndex < getChildCount()) {
+ tmpTv = (TaskView) getChildAt(++nextIndex);
+ if (tmpTv != null && tmpTv.shouldClipViewInStack()) {
+ nextTv = tmpTv;
+ break;
+ }
+ }
+
+ // Clip against the next view, this is just an approximation since we are
+ // stacked and we can make assumptions about the visibility of the this
+ // task relative to the ones in front of it.
+ if (nextTv != null) {
+ // XXX: Can hash the visible rects for this run
+ tv.getHitRect(mTmpRect);
+ nextTv.getHitRect(mTmpRect2);
+ clipBottom = (mTmpRect.bottom - mTmpRect2.top);
+ }
+ }
+ tv.setClipFromBottom(clipBottom);
+ }
+ }
+ if (getChildCount() > 0) {
+ // The front most task should never be clipped
+ TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
+ tv.setClipFromBottom(0);
+ }
+ }
+
/** Sets the current stack scroll */
public void setStackScroll(int value) {
mStackScroll = value;
@@ -641,50 +681,10 @@
Console.AnsiPurple);
}
synchronizeStackViewsWithModel();
+ clipTaskViews();
super.dispatchDraw(canvas);
}
- @Override
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- if (Constants.DebugFlags.App.EnableTaskStackClipping) {
- TaskView tv = (TaskView) child;
- TaskView nextTv = null;
- TaskView tmpTv = null;
- if (tv.shouldClipViewInStack()) {
- int curIndex = indexOfChild(tv);
-
- // Find the next view to clip against
- while (nextTv == null && curIndex < getChildCount()) {
- tmpTv = (TaskView) getChildAt(++curIndex);
- if (tmpTv != null && tmpTv.shouldClipViewInStack()) {
- nextTv = tmpTv;
- }
- }
-
- // Clip against the next view (if we aren't animating its alpha)
- if (nextTv != null) {
- Rect curRect = tv.getClippingRect(mTmpRect);
- Rect nextRect = nextTv.getClippingRect(mTmpRect2);
- // The hit rects are relative to the task view, which needs to be offset by
- // the system bar height
- curRect.offset(0, mConfig.systemInsets.top);
- nextRect.offset(0, mConfig.systemInsets.top);
- // Compute the clip region
- Region clipRegion = new Region();
- clipRegion.op(curRect, Region.Op.UNION);
- clipRegion.op(nextRect, Region.Op.DIFFERENCE);
- // Clip the canvas
- int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
- canvas.clipRegion(clipRegion);
- boolean invalidate = super.drawChild(canvas, child, drawingTime);
- canvas.restoreToCount(saveCount);
- return invalidate;
- }
- }
- }
- return super.drawChild(canvas, child, drawingTime);
- }
-
/** Computes the stack and task rects */
public void computeRects(int width, int height, int insetLeft, int insetBottom) {
// Compute the rects in the stack algorithm
@@ -1155,6 +1155,11 @@
mStack.removeTask(task);
}
+ @Override
+ public void onTaskViewClipStateChanged(TaskView tv) {
+ invalidate(mStackAlgorithm.mStackRect);
+ }
+
/**** RecentsPackageMonitor.PackageCallbacks Implementation ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
index 908e063..9c48896 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -135,9 +135,9 @@
// Set the y translation
if (boundedT < 0f) {
transformOut.translationY = (int) ((Math.max(-numPeekCards, boundedT) /
- numPeekCards) * peekHeight - scaleYOffset - scaleBarYOffset);
+ numPeekCards) * peekHeight - scaleYOffset);
} else {
- transformOut.translationY = (int) (boundedT * overlapHeight - scaleYOffset - scaleBarYOffset);
+ transformOut.translationY = (int) (boundedT * overlapHeight - scaleYOffset);
}
// Set the z translation
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 5524e15..ab14863 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -46,8 +46,9 @@
interface TaskViewCallbacks {
public void onTaskViewAppIconClicked(TaskView tv);
public void onTaskViewAppInfoClicked(TaskView tv);
- public void onTaskViewClicked(TaskView tv, Task t, boolean lockToTask);
+ public void onTaskViewClicked(TaskView tv, Task task, boolean lockToTask);
public void onTaskViewDismissed(TaskView tv);
+ public void onTaskViewClipStateChanged(TaskView tv);
}
RecentsConfiguration mConfig;
@@ -65,7 +66,7 @@
boolean mIsFocused;
boolean mIsStub;
boolean mClipViewInStack;
- Rect mTmpRect = new Rect();
+ int mClipFromBottom;
Paint mLayerPaint = new Paint();
TaskThumbnailView mThumbnailView;
@@ -118,7 +119,9 @@
setOutlineProvider(new ViewOutlineProvider() {
@Override
public boolean getOutline(View view, Outline outline) {
- int height = getHeight() - mMaxFooterHeight + mFooterHeight;
+ // The current height is measured with the footer, so account for the footer height
+ // and the current clip (in the stack)
+ int height = getMeasuredHeight() - mClipFromBottom - mMaxFooterHeight + mFooterHeight;
outline.setRoundRect(0, 0, getWidth(), height,
mConfig.taskViewRoundedCornerRadiusPx);
return true;
@@ -483,15 +486,6 @@
mBarView.setNoUserInteractionState();
}
- /** Returns the rect we want to clip (it may not be the full rect) */
- Rect getClippingRect(Rect outRect) {
- getHitRect(outRect);
- // XXX: We should get the hit rect of the thumbnail view and intersect, but this is faster
- outRect.right = outRect.left + mThumbnailView.getRight();
- outRect.bottom = outRect.top + mThumbnailView.getBottom();
- return outRect;
- }
-
/** Enable the hw layers on this task view */
void enableHwLayers() {
mThumbnailView.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
@@ -506,7 +500,7 @@
mLockToAppButtonView.setLayerType(View.LAYER_TYPE_NONE, mLayerPaint);
}
- /** Sets the stubbed state of this task view. */
+ /** Sets the stubbed state of this task view.
void setStubState(boolean isStub) {
if (!mIsStub && isStub) {
// This is now a stub task view, so clip to the bar height, hide the thumbnail
@@ -519,7 +513,7 @@
mThumbnailView.setVisibility(View.VISIBLE);
}
mIsStub = isStub;
- }
+ } */
/**
* Returns whether this view should be clipped, or any views below should clip against this
@@ -533,19 +527,26 @@
void setClipViewInStack(boolean clip) {
if (clip != mClipViewInStack) {
mClipViewInStack = clip;
- if (getParent() instanceof View) {
- getHitRect(mTmpRect);
- ((View) getParent()).invalidate(mTmpRect);
- }
+ mCb.onTaskViewClipStateChanged(this);
+ }
+ }
+
+ void setClipFromBottom(int clipFromBottom) {
+ clipFromBottom = Math.max(0, Math.min(getMeasuredHeight(), clipFromBottom));
+ if (mClipFromBottom != clipFromBottom) {
+ mClipFromBottom = clipFromBottom;
+ invalidateOutline();
}
}
/** Sets the footer height. */
- public void setFooterHeight(int height) {
- mFooterHeight = height;
- invalidateOutline();
- invalidate(0, getMeasuredHeight() - mMaxFooterHeight, getMeasuredWidth(),
- getMeasuredHeight());
+ public void setFooterHeight(int footerHeight) {
+ if (footerHeight != mFooterHeight) {
+ mFooterHeight = footerHeight;
+ invalidateOutline();
+ invalidate(0, getMeasuredHeight() - mMaxFooterHeight, getMeasuredWidth(),
+ getMeasuredHeight());
+ }
}
/** Gets the footer height. */
@@ -677,6 +678,7 @@
mTask = t;
mTask.setCallbacks(this);
if (getMeasuredWidth() == 0) {
+ // If we haven't yet measured, we should just set the footer height with any animation
animateFooterVisibility(t.canLockToTask, 0, 0);
} else {
animateFooterVisibility(t.canLockToTask, mConfig.taskViewLockToAppLongAnimDuration, 0);