Merge "DO NOT MERGE Fixing some regressions" into lmp-dev
This commit is contained in:
@@ -32,7 +32,7 @@ public class Constants {
|
||||
// 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
|
||||
|
||||
@@ -458,8 +458,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
filter.addAction(ACTION_TOGGLE_RECENTS_ACTIVITY);
|
||||
filter.addAction(ACTION_START_ENTER_ANIMATION);
|
||||
registerReceiver(mServiceBroadcastReceiver, filter);
|
||||
|
||||
mVisible = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -485,6 +483,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
mVisible = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -72,7 +72,12 @@ public class ReferenceCountedTrigger {
|
||||
|
||||
/** 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 */
|
||||
|
||||
@@ -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 @@ public class Utilities {
|
||||
}
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
|
||||
@@ -29,6 +29,6 @@ class BitmapLruCache extends KeyStoreLruCache<Bitmap> {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,6 @@ class DrawableLruCache extends KeyStoreLruCache<Drawable> {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -73,11 +73,6 @@ public class KeyStoreLruCache<V> {
|
||||
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);
|
||||
|
||||
@@ -45,7 +45,7 @@ public class RecentsPackageMonitor extends PackageMonitor {
|
||||
mSystemServicesProxy = new SystemServicesProxy(context);
|
||||
mCb = cb;
|
||||
try {
|
||||
register(context, Looper.getMainLooper(), false);
|
||||
register(context, Looper.getMainLooper(), true);
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -27,38 +27,29 @@ import android.graphics.drawable.Drawable;
|
||||
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 @@ class TaskResourceLoadQueue {
|
||||
* 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 @@ class TaskResourceLoadQueue {
|
||||
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 @@ class TaskResourceLoadQueue {
|
||||
Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|clearTasks]");
|
||||
}
|
||||
mQueue.clear();
|
||||
mForceLoadSet.clear();
|
||||
}
|
||||
|
||||
/** Returns whether the load queue is empty */
|
||||
@@ -119,19 +100,20 @@ class TaskResourceLoader implements Runnable {
|
||||
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 @@ class TaskResourceLoader implements Runnable {
|
||||
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 @@ public class RecentsTaskLoader {
|
||||
/** 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 @@ public class RecentsTaskLoader {
|
||||
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 @@ public class RecentsTaskLoader {
|
||||
}
|
||||
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 @@ public class RecentsTaskLoader {
|
||||
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 @@ public class RecentsTaskLoader {
|
||||
} 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 @@ public class RecentsTaskLoader {
|
||||
}
|
||||
|
||||
// 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 @@ public class RecentsTaskLoader {
|
||||
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 @@ public class RecentsTaskLoader {
|
||||
requiresLoad = true;
|
||||
}
|
||||
if (requiresLoad) {
|
||||
mLoadQueue.addTask(t, false);
|
||||
mLoadQueue.addTask(t);
|
||||
}
|
||||
t.notifyTaskDataLoaded(thumbnail, applicationIcon);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.recents.model;
|
||||
|
||||
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 class Task {
|
||||
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 @@ public class Task {
|
||||
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;
|
||||
|
||||
@@ -320,7 +320,7 @@ public class TaskStack {
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -191,10 +191,6 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
|
||||
/** 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
@@ -162,11 +162,10 @@ class TaskBarView extends FrameLayout {
|
||||
}
|
||||
// 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 */
|
||||
|
||||
@@ -302,7 +302,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
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 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
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 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
mStack.removeTask(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskViewClipStateChanged(TaskView tv) {
|
||||
invalidate(mStackAlgorithm.mStackRect);
|
||||
}
|
||||
|
||||
/**** RecentsPackageMonitor.PackageCallbacks Implementation ****/
|
||||
|
||||
@Override
|
||||
|
||||
@@ -135,9 +135,9 @@ public class TaskStackViewLayoutAlgorithm {
|
||||
// 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
|
||||
|
||||
@@ -46,8 +46,9 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
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 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
boolean mIsFocused;
|
||||
boolean mIsStub;
|
||||
boolean mClipViewInStack;
|
||||
Rect mTmpRect = new Rect();
|
||||
int mClipFromBottom;
|
||||
Paint mLayerPaint = new Paint();
|
||||
|
||||
TaskThumbnailView mThumbnailView;
|
||||
@@ -118,7 +119,9 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
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 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
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 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
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 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
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 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
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 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user