Merge "Adding activity icon to the task view"
This commit is contained in:
@@ -28,21 +28,29 @@
|
||||
android:layout_gravity="top|center_horizontal"
|
||||
android:background="#e6444444">
|
||||
<ImageView
|
||||
android:id="@+id/activity_icon"
|
||||
android:layout_width="@dimen/recents_task_view_icon_size"
|
||||
android:layout_height="@dimen/recents_task_view_icon_size"
|
||||
android:layout_gravity="top|left"
|
||||
android:id="@+id/application_icon"
|
||||
android:layout_width="@dimen/recents_task_view_application_icon_size"
|
||||
android:layout_height="@dimen/recents_task_view_application_icon_size"
|
||||
android:layout_gravity="center_vertical|left"
|
||||
android:padding="8dp" />
|
||||
<TextView
|
||||
android:id="@+id/activity_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|left"
|
||||
android:layout_marginLeft="@dimen/recents_task_view_icon_size"
|
||||
android:layout_marginLeft="@dimen/recents_task_view_application_icon_size"
|
||||
android:layout_marginRight="@dimen/recents_task_view_activity_icon_size"
|
||||
android:textSize="24sp"
|
||||
android:textColor="#ffffffff"
|
||||
android:text="@string/recents_empty_message"
|
||||
android:fontFamily="sans-serif-thin" />
|
||||
<ImageView
|
||||
android:id="@+id/activity_icon"
|
||||
android:layout_width="@dimen/recents_task_view_activity_icon_size"
|
||||
android:layout_height="@dimen/recents_task_view_activity_icon_size"
|
||||
android:layout_gravity="center_vertical|right"
|
||||
android:padding="12dp"
|
||||
android:visibility="invisible" />
|
||||
</com.android.systemui.recents.views.TaskBarView>
|
||||
</com.android.systemui.recents.views.TaskView>
|
||||
|
||||
|
||||
@@ -230,8 +230,11 @@
|
||||
<!-- Default distance from each snap target that GlowPadView considers a "hit" -->
|
||||
<dimen name="glowpadview_inner_radius">15dip</dimen>
|
||||
|
||||
<!-- The size of the icon in the recents task view. -->
|
||||
<dimen name="recents_task_view_icon_size">60dp</dimen>
|
||||
<!-- The size of the application icon in the recents task view. -->
|
||||
<dimen name="recents_task_view_application_icon_size">60dp</dimen>
|
||||
|
||||
<!-- The size of the activity icon in the recents task view. -->
|
||||
<dimen name="recents_task_view_activity_icon_size">60dp</dimen>
|
||||
|
||||
<!-- Space below the notification stack -->
|
||||
<dimen name="notification_stack_margin_bottom">0dp</dimen>
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemService;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
@@ -110,17 +110,18 @@ class TaskResourceLoader implements Runnable {
|
||||
|
||||
SystemServicesProxy mSystemServicesProxy;
|
||||
TaskResourceLoadQueue mLoadQueue;
|
||||
DrawableLruCache mIconCache;
|
||||
DrawableLruCache mApplicationIconCache;
|
||||
BitmapLruCache mThumbnailCache;
|
||||
|
||||
boolean mCancelled;
|
||||
boolean mWaitingOnLoadQueue;
|
||||
|
||||
/** Constructor, creates a new loading thread that loads task resources in the background */
|
||||
public TaskResourceLoader(TaskResourceLoadQueue loadQueue, DrawableLruCache iconCache,
|
||||
public TaskResourceLoader(TaskResourceLoadQueue loadQueue,
|
||||
DrawableLruCache applicationIconCache,
|
||||
BitmapLruCache thumbnailCache) {
|
||||
mLoadQueue = loadQueue;
|
||||
mIconCache = iconCache;
|
||||
mApplicationIconCache = applicationIconCache;
|
||||
mThumbnailCache = thumbnailCache;
|
||||
mMainThreadHandler = new Handler();
|
||||
mLoadThread = new HandlerThread("Recents-TaskResourceLoader");
|
||||
@@ -184,13 +185,13 @@ class TaskResourceLoader implements Runnable {
|
||||
final Task t = nextTaskData.first;
|
||||
final boolean forceLoadTask = nextTaskData.second;
|
||||
if (t != null) {
|
||||
Drawable loadIcon = mIconCache.get(t.key);
|
||||
Drawable loadIcon = mApplicationIconCache.get(t.key);
|
||||
Bitmap loadThumbnail = mThumbnailCache.get(t.key);
|
||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||
" [TaskResourceLoader|load]",
|
||||
t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail +
|
||||
" forceLoad: " + forceLoadTask);
|
||||
// Load the icon
|
||||
// Load the application icon
|
||||
if (loadIcon == null || forceLoadTask) {
|
||||
ActivityInfo info = ssp.getActivityInfo(t.key.baseIntent.getComponent());
|
||||
Drawable icon = ssp.getActivityIcon(info);
|
||||
@@ -200,7 +201,7 @@ class TaskResourceLoader implements Runnable {
|
||||
" [TaskResourceLoader|loadIcon]",
|
||||
icon);
|
||||
loadIcon = icon;
|
||||
mIconCache.put(t.key, icon);
|
||||
mApplicationIconCache.put(t.key, icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,7 +294,7 @@ public class RecentsTaskLoader {
|
||||
static RecentsTaskLoader sInstance;
|
||||
|
||||
SystemServicesProxy mSystemServicesProxy;
|
||||
DrawableLruCache mIconCache;
|
||||
DrawableLruCache mApplicationIconCache;
|
||||
BitmapLruCache mThumbnailCache;
|
||||
TaskResourceLoadQueue mLoadQueue;
|
||||
TaskResourceLoader mLoader;
|
||||
@@ -301,7 +302,7 @@ public class RecentsTaskLoader {
|
||||
int mMaxThumbnailCacheSize;
|
||||
int mMaxIconCacheSize;
|
||||
|
||||
BitmapDrawable mDefaultIcon;
|
||||
BitmapDrawable mDefaultApplicationIcon;
|
||||
Bitmap mDefaultThumbnail;
|
||||
|
||||
/** Private Constructor */
|
||||
@@ -324,9 +325,9 @@ public class RecentsTaskLoader {
|
||||
// Initialize the proxy, cache and loaders
|
||||
mSystemServicesProxy = new SystemServicesProxy(context);
|
||||
mLoadQueue = new TaskResourceLoadQueue();
|
||||
mIconCache = new DrawableLruCache(iconCacheSize);
|
||||
mApplicationIconCache = new DrawableLruCache(iconCacheSize);
|
||||
mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
|
||||
mLoader = new TaskResourceLoader(mLoadQueue, mIconCache, mThumbnailCache);
|
||||
mLoader = new TaskResourceLoader(mLoadQueue, mApplicationIconCache, mThumbnailCache);
|
||||
|
||||
// Create the default assets
|
||||
Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
|
||||
@@ -337,10 +338,10 @@ public class RecentsTaskLoader {
|
||||
c.setBitmap(mDefaultThumbnail);
|
||||
c.drawColor(0x00000000);
|
||||
c.setBitmap(null);
|
||||
mDefaultIcon = new BitmapDrawable(context.getResources(), icon);
|
||||
mDefaultApplicationIcon = new BitmapDrawable(context.getResources(), icon);
|
||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||
"[RecentsTaskLoader|defaultBitmaps]",
|
||||
"icon: " + mDefaultIcon + " thumbnail: " + mDefaultThumbnail, Console.AnsiRed);
|
||||
"icon: " + mDefaultApplicationIcon + " thumbnail: " + mDefaultThumbnail, Console.AnsiRed);
|
||||
}
|
||||
|
||||
/** Initializes the recents task loader */
|
||||
@@ -406,41 +407,36 @@ public class RecentsTaskLoader {
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
ActivityManager.RecentTaskInfo t = tasks.get(i);
|
||||
ActivityInfo info = ssp.getActivityInfo(t.baseIntent.getComponent());
|
||||
String title = ssp.getActivityLabel(info);
|
||||
String activityLabel = (t.activityLabel == null ? ssp.getActivityLabel(info) :
|
||||
t.activityLabel.toString());
|
||||
Bitmap activityIcon = t.activityIcon;
|
||||
boolean isForemostTask = (i == (taskCount - 1));
|
||||
|
||||
// Create a new task
|
||||
Task task = new Task(t.persistentId, (t.id > -1), t.baseIntent, activityLabel,
|
||||
activityIcon);
|
||||
|
||||
// Preload the specified number of apps
|
||||
if (i >= (taskCount - preloadCount)) {
|
||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||
"[RecentsTaskLoader|preloadTask]",
|
||||
"i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
|
||||
|
||||
String label = (t.activityLabel == null ? title : t.activityLabel.toString());
|
||||
BitmapDrawable bd = null;
|
||||
if (t.activityIcon != null) {
|
||||
bd = new BitmapDrawable(res, t.activityIcon);
|
||||
}
|
||||
Task task = new Task(t.persistentId, (t.id > -1), t.baseIntent, label, bd);
|
||||
|
||||
// Load the icon (if possible and not the foremost task, from the cache)
|
||||
if (task.icon != null) {
|
||||
mIconCache.put(task.key, task.icon);
|
||||
} else {
|
||||
if (!isForemostTask) {
|
||||
task.icon = mIconCache.get(task.key);
|
||||
if (task.icon != null) {
|
||||
// Even though we get things from the cache, we should update them
|
||||
// if they've changed in the bg
|
||||
tasksToForceLoad.add(task);
|
||||
}
|
||||
if (!isForemostTask) {
|
||||
task.applicationIcon = mApplicationIconCache.get(task.key);
|
||||
if (task.applicationIcon != null) {
|
||||
// Even though we get things from the cache, we should update them
|
||||
// if they've changed in the bg
|
||||
tasksToForceLoad.add(task);
|
||||
}
|
||||
if (task.icon == null) {
|
||||
task.icon = ssp.getActivityIcon(info);
|
||||
if (task.icon != null) {
|
||||
mIconCache.put(task.key, task.icon);
|
||||
} else {
|
||||
task.icon = mDefaultIcon;
|
||||
}
|
||||
}
|
||||
if (task.applicationIcon == null) {
|
||||
task.applicationIcon = ssp.getActivityIcon(info);
|
||||
if (task.applicationIcon != null) {
|
||||
mApplicationIconCache.put(task.key, task.applicationIcon);
|
||||
} else {
|
||||
task.applicationIcon = mDefaultApplicationIcon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,18 +459,12 @@ public class RecentsTaskLoader {
|
||||
task.thumbnail = mDefaultThumbnail;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the task to the stack
|
||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
|
||||
stack.addTask(task);
|
||||
} else {
|
||||
// Add the task to the stack
|
||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
|
||||
stack.addTask(new Task(t.persistentId, (t.id > -1), t.baseIntent, title,
|
||||
null, null));
|
||||
}
|
||||
|
||||
// Add the task to the stack
|
||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
|
||||
stack.addTask(task);
|
||||
}
|
||||
Console.log(Constants.DebugFlags.App.TimeSystemCalls,
|
||||
"[RecentsTaskLoader|getAllTaskTopThumbnail]",
|
||||
@@ -507,16 +497,16 @@ public class RecentsTaskLoader {
|
||||
|
||||
/** Acquires the task resource data from the pool. */
|
||||
public void loadTaskData(Task t) {
|
||||
Drawable icon = mIconCache.get(t.key);
|
||||
Drawable applicationIcon = mApplicationIconCache.get(t.key);
|
||||
Bitmap thumbnail = mThumbnailCache.get(t.key);
|
||||
|
||||
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
|
||||
t + " icon: " + icon + " thumbnail: " + thumbnail +
|
||||
t + " applicationIcon: " + applicationIcon + " thumbnail: " + thumbnail +
|
||||
" thumbnailCacheSize: " + mThumbnailCache.size());
|
||||
|
||||
boolean requiresLoad = false;
|
||||
if (icon == null) {
|
||||
icon = mDefaultIcon;
|
||||
if (applicationIcon == null) {
|
||||
applicationIcon = mDefaultApplicationIcon;
|
||||
requiresLoad = true;
|
||||
}
|
||||
if (thumbnail == null) {
|
||||
@@ -526,7 +516,7 @@ public class RecentsTaskLoader {
|
||||
if (requiresLoad) {
|
||||
mLoadQueue.addTask(t, false);
|
||||
}
|
||||
t.notifyTaskDataLoaded(thumbnail, icon, false);
|
||||
t.notifyTaskDataLoaded(thumbnail, applicationIcon, false);
|
||||
}
|
||||
|
||||
/** Releases the task resource data back into the pool. */
|
||||
@@ -536,7 +526,7 @@ public class RecentsTaskLoader {
|
||||
" thumbnailCacheSize: " + mThumbnailCache.size());
|
||||
|
||||
mLoadQueue.removeTask(t);
|
||||
t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
|
||||
t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultApplicationIcon);
|
||||
}
|
||||
|
||||
/** Completely removes the resource data from the pool. */
|
||||
@@ -546,8 +536,8 @@ public class RecentsTaskLoader {
|
||||
|
||||
mLoadQueue.removeTask(t);
|
||||
mThumbnailCache.remove(t.key);
|
||||
mIconCache.remove(t.key);
|
||||
t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
|
||||
mApplicationIconCache.remove(t.key);
|
||||
t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultApplicationIcon);
|
||||
}
|
||||
|
||||
/** Stops the task loader and clears all pending tasks */
|
||||
@@ -570,19 +560,19 @@ public class RecentsTaskLoader {
|
||||
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
|
||||
// We are leaving recents, so trim the data a bit
|
||||
mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
|
||||
mIconCache.trimToSize(mMaxIconCacheSize / 2);
|
||||
mApplicationIconCache.trimToSize(mMaxIconCacheSize / 2);
|
||||
break;
|
||||
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
|
||||
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
|
||||
// We are going to be low on memory
|
||||
mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
|
||||
mIconCache.trimToSize(mMaxIconCacheSize / 4);
|
||||
mApplicationIconCache.trimToSize(mMaxIconCacheSize / 4);
|
||||
break;
|
||||
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
|
||||
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
|
||||
// We are low on memory, so release everything
|
||||
mThumbnailCache.evictAll();
|
||||
mIconCache.evictAll();
|
||||
mApplicationIconCache.evictAll();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.graphics.drawable.Drawable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Acts as a shim around the real system services that we need to access data from, and provides
|
||||
@@ -76,8 +77,11 @@ public class SystemServicesProxy {
|
||||
rti.id = rti.persistentId = i;
|
||||
rti.baseIntent = new Intent();
|
||||
rti.baseIntent.setComponent(cn);
|
||||
rti.description = rti.activityLabel = "Recent Task";
|
||||
rti.activityIcon = Bitmap.createBitmap(mDummyIcon);
|
||||
rti.description = rti.activityLabel =
|
||||
Long.toString(Math.abs(new Random().nextLong()), 36);
|
||||
if (i % 2 == 0) {
|
||||
rti.activityIcon = Bitmap.createBitmap(mDummyIcon);
|
||||
}
|
||||
tasks.add(rti);
|
||||
}
|
||||
return tasks;
|
||||
|
||||
@@ -60,23 +60,19 @@ public class Task {
|
||||
}
|
||||
|
||||
public TaskKey key;
|
||||
public String title;
|
||||
public Drawable icon;
|
||||
public Drawable applicationIcon;
|
||||
public String activityLabel;
|
||||
public Bitmap activityIcon;
|
||||
public Bitmap thumbnail;
|
||||
public boolean isActive;
|
||||
|
||||
TaskCallbacks mCb;
|
||||
|
||||
public Task(int id, boolean isActive, Intent intent, String activityTitle, Drawable icon) {
|
||||
this(id, isActive, intent, activityTitle, icon, null);
|
||||
}
|
||||
|
||||
public Task(int id, boolean isActive, Intent intent, String activityTitle, Drawable icon,
|
||||
Bitmap thumbnail) {
|
||||
public Task(int id, boolean isActive, Intent intent, String activityTitle,
|
||||
Bitmap activityIcon) {
|
||||
this.key = new TaskKey(id, intent);
|
||||
this.title = activityTitle;
|
||||
this.icon = icon;
|
||||
this.thumbnail = thumbnail;
|
||||
this.activityLabel = activityTitle;
|
||||
this.activityIcon = activityIcon;
|
||||
this.isActive = isActive;
|
||||
}
|
||||
|
||||
@@ -86,8 +82,9 @@ public class Task {
|
||||
}
|
||||
|
||||
/** Notifies the callback listeners that this task has been loaded */
|
||||
public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon, boolean reloadingTaskData) {
|
||||
this.icon = icon;
|
||||
public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon,
|
||||
boolean reloadingTaskData) {
|
||||
this.applicationIcon = applicationIcon;
|
||||
this.thumbnail = thumbnail;
|
||||
if (mCb != null) {
|
||||
mCb.onTaskDataLoaded(reloadingTaskData);
|
||||
@@ -95,8 +92,8 @@ public class Task {
|
||||
}
|
||||
|
||||
/** Notifies the callback listeners that this task has been unloaded */
|
||||
public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultIcon) {
|
||||
icon = defaultIcon;
|
||||
public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultApplicationIcon) {
|
||||
applicationIcon = defaultApplicationIcon;
|
||||
thumbnail = defaultThumbnail;
|
||||
if (mCb != null) {
|
||||
mCb.onTaskDataUnloaded();
|
||||
|
||||
@@ -17,21 +17,12 @@
|
||||
package com.android.systemui.recents.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.Constants;
|
||||
import com.android.systemui.recents.RecentsConfiguration;
|
||||
import com.android.systemui.recents.model.Task;
|
||||
|
||||
|
||||
@@ -39,6 +30,7 @@ import com.android.systemui.recents.model.Task;
|
||||
class TaskBarView extends FrameLayout {
|
||||
Task mTask;
|
||||
|
||||
ImageView mApplicationIcon;
|
||||
ImageView mActivityIcon;
|
||||
TextView mActivityDescription;
|
||||
|
||||
@@ -61,6 +53,7 @@ class TaskBarView extends FrameLayout {
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
// Initialize the icon and description views
|
||||
mApplicationIcon = (ImageView) findViewById(R.id.application_icon);
|
||||
mActivityIcon = (ImageView) findViewById(R.id.activity_icon);
|
||||
mActivityDescription = (TextView) findViewById(R.id.activity_description);
|
||||
}
|
||||
@@ -68,9 +61,13 @@ class TaskBarView extends FrameLayout {
|
||||
/** Binds the bar view to the task */
|
||||
void rebindToTask(Task t, boolean animate) {
|
||||
mTask = t;
|
||||
if (t.icon != null) {
|
||||
mActivityIcon.setImageDrawable(t.icon);
|
||||
mActivityDescription.setText(t.title);
|
||||
if (t.applicationIcon != null) {
|
||||
mApplicationIcon.setImageDrawable(t.applicationIcon);
|
||||
mActivityDescription.setText(t.activityLabel);
|
||||
if (t.activityIcon != null) {
|
||||
mActivityIcon.setImageBitmap(t.activityIcon);
|
||||
mActivityIcon.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (animate) {
|
||||
// XXX: Investigate how expensive it will be to create a second bitmap and crossfade
|
||||
}
|
||||
@@ -80,7 +77,9 @@ class TaskBarView extends FrameLayout {
|
||||
/** Unbinds the bar view from the task */
|
||||
void unbindFromTask() {
|
||||
mTask = null;
|
||||
mActivityIcon.setImageDrawable(null);
|
||||
mApplicationIcon.setImageDrawable(null);
|
||||
mActivityIcon.setImageBitmap(null);
|
||||
mActivityIcon.setVisibility(View.INVISIBLE);
|
||||
mActivityDescription.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task.
|
||||
// Bind the views
|
||||
mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
|
||||
mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
|
||||
mBarView.mActivityIcon.setOnClickListener(this);
|
||||
mBarView.mApplicationIcon.setOnClickListener(this);
|
||||
if (mTaskDataLoaded) {
|
||||
onTaskDataLoaded(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user