Merge changes Iac20cc7b,I87ce6320
* changes: Fixing potential issue with wrong task descriptions being loaded. Refactoring to AnimatedEvent.
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
android:layout_height="@dimen/recents_task_bar_height"
|
||||
android:layout_gravity="top|center_horizontal">
|
||||
<com.android.systemui.recents.views.FixedSizeImageView
|
||||
android:id="@+id/application_icon"
|
||||
android:id="@+id/icon"
|
||||
android:contentDescription="@string/recents_app_info_button_label"
|
||||
android:layout_width="@dimen/recents_task_view_application_icon_size"
|
||||
android:layout_height="@dimen/recents_task_view_application_icon_size"
|
||||
@@ -29,7 +29,7 @@
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/recents_button_bg" />
|
||||
<TextView
|
||||
android:id="@+id/activity_description"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
|
||||
@@ -246,10 +246,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
boolean dismissHistory() {
|
||||
// Try and hide the history view first
|
||||
if (mHistoryView != null && mHistoryView.isVisible()) {
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this);
|
||||
t.increment();
|
||||
EventBus.getDefault().send(new HideHistoryEvent(true /* animate */, t));
|
||||
t.decrement();
|
||||
EventBus.getDefault().send(new HideHistoryEvent(true /* animate */));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -301,8 +298,8 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
*/
|
||||
void dismissRecentsToHome(boolean animated) {
|
||||
if (animated) {
|
||||
ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
|
||||
null, mFinishLaunchHomeRunnable, null);
|
||||
ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(null,
|
||||
mFinishLaunchHomeRunnable, null);
|
||||
mRecentsView.startExitToHomeAnimation(
|
||||
new ViewAnimation.TaskViewExitContext(exitTrigger));
|
||||
} else {
|
||||
@@ -439,10 +436,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
// Reset some states
|
||||
mIgnoreAltTabRelease = false;
|
||||
if (mHistoryView != null) {
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this);
|
||||
t.increment();
|
||||
EventBus.getDefault().send(new HideHistoryEvent(false /* animate */, t));
|
||||
t.decrement();
|
||||
EventBus.getDefault().send(new HideHistoryEvent(false /* animate */));
|
||||
}
|
||||
|
||||
// Notify that recents is now hidden
|
||||
@@ -511,11 +505,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
if (savedInstanceState.getBoolean(KEY_SAVED_STATE_HISTORY_VISIBLE, false)) {
|
||||
ReferenceCountedTrigger postHideStackAnimationTrigger =
|
||||
new ReferenceCountedTrigger(this);
|
||||
postHideStackAnimationTrigger.increment();
|
||||
EventBus.getDefault().send(new ShowHistoryEvent(postHideStackAnimationTrigger));
|
||||
postHideStackAnimationTrigger.decrement();
|
||||
EventBus.getDefault().send(new ShowHistoryEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,16 +634,14 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
} else if (event.triggeredFromHomeKey) {
|
||||
// Otherwise, dismiss Recents to Home
|
||||
if (mHistoryView != null && mHistoryView.isVisible()) {
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this);
|
||||
t.increment();
|
||||
t.addLastDecrementRunnable(new Runnable() {
|
||||
HideHistoryEvent hideEvent = new HideHistoryEvent(true /* animate */);
|
||||
hideEvent.addPostAnimationCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dismissRecentsToHome(true /* animated */);
|
||||
}
|
||||
});
|
||||
EventBus.getDefault().send(new HideHistoryEvent(true, t));
|
||||
t.decrement();
|
||||
EventBus.getDefault().send(hideEvent);
|
||||
|
||||
} else {
|
||||
dismissRecentsToHome(true /* animated */);
|
||||
@@ -665,7 +653,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
|
||||
public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
|
||||
// Try and start the enter animation (or restart it on configuration changed)
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this);
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger();
|
||||
ViewAnimation.TaskViewEnterContext ctx = new ViewAnimation.TaskViewEnterContext(t);
|
||||
ctx.postAnimationTrigger.increment();
|
||||
if (mSearchWidgetInfo != null) {
|
||||
@@ -784,11 +772,11 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
// provided.
|
||||
mHistoryView.setSystemInsets(mRecentsView.getSystemInsets());
|
||||
}
|
||||
mHistoryView.show(mRecentsView.getTaskStack(), event.postHideStackAnimationTrigger);
|
||||
mHistoryView.show(mRecentsView.getTaskStack(), event.getAnimationTrigger());
|
||||
}
|
||||
|
||||
public final void onBusEvent(HideHistoryEvent event) {
|
||||
mHistoryView.hide(event.animate, event.postHideHistoryAnimationTrigger);
|
||||
mHistoryView.hide(event.animate, event.getAnimationTrigger());
|
||||
}
|
||||
|
||||
private void refreshSearchWidgetView() {
|
||||
|
||||
@@ -207,7 +207,7 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub implements
|
||||
RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
|
||||
loader.preloadTasks(plan, true /* isTopTaskHome */);
|
||||
RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
|
||||
launchOpts.numVisibleTasks = loader.getApplicationIconCacheSize();
|
||||
launchOpts.numVisibleTasks = loader.getIconCacheSize();
|
||||
launchOpts.numVisibleTaskThumbnails = loader.getThumbnailCacheSize();
|
||||
launchOpts.onlyLoadForCache = true;
|
||||
loader.loadTasks(mContext, plan, launchOpts);
|
||||
@@ -452,7 +452,7 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub implements
|
||||
}
|
||||
|
||||
// Launch the task
|
||||
ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.activityLabel, launchOpts);
|
||||
ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.title, launchOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -524,7 +524,7 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub implements
|
||||
MetricsLogger.count(mContext, "overview_affiliated_task_launch", 1);
|
||||
|
||||
// Launch the task
|
||||
ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.activityLabel, launchOpts);
|
||||
ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.title, launchOpts);
|
||||
}
|
||||
|
||||
public void showNextAffiliatedTask() {
|
||||
|
||||
@@ -28,6 +28,8 @@ import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.MutableBoolean;
|
||||
|
||||
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -220,6 +222,20 @@ public class EventBus extends BroadcastReceiver {
|
||||
// Only accessible from derived events
|
||||
protected Event() {}
|
||||
|
||||
/**
|
||||
* Called by the EventBus prior to dispatching this event to any subscriber of this event.
|
||||
*/
|
||||
void onPreDispatch() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the EventBus after dispatching this event to every subscriber of this event.
|
||||
*/
|
||||
void onPostDispatch() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
Event evt = (Event) super.clone();
|
||||
@@ -229,6 +245,51 @@ public class EventBus extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An event that represents an animated state change, which allows subscribers to coordinate
|
||||
* callbacks which happen after the animation has taken place.
|
||||
*
|
||||
* Internally, it is guaranteed that increment() and decrement() will be called before and the
|
||||
* after the event is dispatched.
|
||||
*/
|
||||
public static class AnimatedEvent extends Event {
|
||||
|
||||
private final ReferenceCountedTrigger mTrigger = new ReferenceCountedTrigger();
|
||||
|
||||
// Only accessible from derived events
|
||||
protected AnimatedEvent() {}
|
||||
|
||||
/**
|
||||
* Returns the reference counted trigger that coordinates the animations for this event.
|
||||
*/
|
||||
public ReferenceCountedTrigger getAnimationTrigger() {
|
||||
return mTrigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback that is guaranteed to be called after the state has changed regardless of
|
||||
* whether an actual animation took place.
|
||||
*/
|
||||
public void addPostAnimationCallback(Runnable r) {
|
||||
mTrigger.addLastDecrementRunnable(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onPreDispatch() {
|
||||
mTrigger.increment();
|
||||
}
|
||||
|
||||
@Override
|
||||
void onPostDispatch() {
|
||||
mTrigger.decrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An inter-process event super class that allows us to track user state across subscriber
|
||||
* invocations.
|
||||
@@ -706,6 +767,11 @@ public class EventBus extends BroadcastReceiver {
|
||||
if (eventHandlers == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare this event
|
||||
boolean hasPostedEvent = false;
|
||||
event.onPreDispatch();
|
||||
|
||||
// We need to clone the list in case a subscriber unregisters itself during traversal
|
||||
eventHandlers = (ArrayList<EventHandler>) eventHandlers.clone();
|
||||
for (final EventHandler eventHandler : eventHandlers) {
|
||||
@@ -717,11 +783,24 @@ public class EventBus extends BroadcastReceiver {
|
||||
processEvent(eventHandler, event);
|
||||
}
|
||||
});
|
||||
hasPostedEvent = true;
|
||||
} else {
|
||||
processEvent(eventHandler, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up after this event, deferring until all subscribers have been called
|
||||
if (hasPostedEvent) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
event.onPostDispatch();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
event.onPostDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,17 +22,11 @@ import com.android.systemui.recents.misc.ReferenceCountedTrigger;
|
||||
/**
|
||||
* This is sent when the history view will be closed.
|
||||
*/
|
||||
public class HideHistoryEvent extends EventBus.Event {
|
||||
public class HideHistoryEvent extends EventBus.AnimatedEvent {
|
||||
|
||||
public final boolean animate;
|
||||
public final ReferenceCountedTrigger postHideHistoryAnimationTrigger;
|
||||
|
||||
/**
|
||||
* @param postHideHistoryAnimationTrigger the trigger that gets called when all the history animations are finished
|
||||
* when transitioning from the history view
|
||||
*/
|
||||
public HideHistoryEvent(boolean animate, ReferenceCountedTrigger postHideHistoryAnimationTrigger) {
|
||||
public HideHistoryEvent(boolean animate) {
|
||||
this.animate = animate;
|
||||
this.postHideHistoryAnimationTrigger = postHideHistoryAnimationTrigger;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,15 +22,8 @@ import com.android.systemui.recents.misc.ReferenceCountedTrigger;
|
||||
/**
|
||||
* This is sent when the history view button is clicked.
|
||||
*/
|
||||
public class ShowHistoryEvent extends EventBus.Event {
|
||||
public class ShowHistoryEvent extends EventBus.AnimatedEvent {
|
||||
|
||||
public final ReferenceCountedTrigger postHideStackAnimationTrigger;
|
||||
// Simple event
|
||||
|
||||
/**
|
||||
* @param postHideStackAnimationTrigger the trigger that gets called when all the task animations are finished when
|
||||
* transitioning to the history view
|
||||
*/
|
||||
public ShowHistoryEvent(ReferenceCountedTrigger postHideStackAnimationTrigger) {
|
||||
this.postHideStackAnimationTrigger = postHideStackAnimationTrigger;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,18 +25,15 @@ import com.android.systemui.recents.views.TaskView;
|
||||
/**
|
||||
* This event is sent whenever a drag ends.
|
||||
*/
|
||||
public class DragEndEvent extends EventBus.Event {
|
||||
public class DragEndEvent extends EventBus.AnimatedEvent {
|
||||
|
||||
public final Task task;
|
||||
public final TaskView taskView;
|
||||
public final DropTarget dropTarget;
|
||||
public final ReferenceCountedTrigger postAnimationTrigger;
|
||||
|
||||
public DragEndEvent(Task task, TaskView taskView, DropTarget dropTarget,
|
||||
ReferenceCountedTrigger postAnimationTrigger) {
|
||||
public DragEndEvent(Task task, TaskView taskView, DropTarget dropTarget) {
|
||||
this.task = task;
|
||||
this.taskView = taskView;
|
||||
this.dropTarget = dropTarget;
|
||||
this.postAnimationTrigger = postAnimationTrigger;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.activity.HideHistoryButtonEvent;
|
||||
import com.android.systemui.recents.events.activity.HideHistoryEvent;
|
||||
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
|
||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||
import com.android.systemui.recents.model.RecentsTaskLoader;
|
||||
import com.android.systemui.recents.model.Task;
|
||||
@@ -72,7 +71,7 @@ public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAd
|
||||
public void onTaskDataLoaded(Task task) {
|
||||
// This callback is only made for TaskRow view holders
|
||||
ImageView iv = (ImageView) content.findViewById(R.id.icon);
|
||||
iv.setImageDrawable(task.applicationIcon);
|
||||
iv.setImageDrawable(task.icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,7 +127,7 @@ public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAd
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
ssp.startActivityFromRecents(v.getContext(), task.key.id, task.activityLabel,
|
||||
ssp.startActivityFromRecents(v.getContext(), task.key.id, task.title,
|
||||
ActivityOptions.makeBasic());
|
||||
}
|
||||
|
||||
@@ -240,7 +239,7 @@ public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAd
|
||||
TaskRow taskRow = (TaskRow) row;
|
||||
taskRow.task.addCallback(holder);
|
||||
TextView tv = (TextView) holder.content.findViewById(R.id.description);
|
||||
tv.setText(taskRow.task.activityLabel);
|
||||
tv.setText(taskRow.task.title);
|
||||
holder.content.setOnClickListener(taskRow);
|
||||
loader.loadTaskData(taskRow.task);
|
||||
break;
|
||||
@@ -313,10 +312,7 @@ public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAd
|
||||
* Dismisses history back to the stack view.
|
||||
*/
|
||||
private void dismissHistory() {
|
||||
ReferenceCountedTrigger t = new ReferenceCountedTrigger(mContext);
|
||||
t.increment();
|
||||
EventBus.getDefault().send(new HideHistoryEvent(true /* animate */, t));
|
||||
t.decrement();
|
||||
EventBus.getDefault().send(new HideHistoryEvent(true /* animate */));
|
||||
EventBus.getDefault().send(new HideHistoryButtonEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,6 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class ReferenceCountedTrigger {
|
||||
|
||||
private static final String TAG = "ReferenceCountedTrigger";
|
||||
|
||||
Context mContext;
|
||||
int mCount;
|
||||
ArrayList<Runnable> mFirstIncRunnables = new ArrayList<Runnable>();
|
||||
ArrayList<Runnable> mLastDecRunnables = new ArrayList<Runnable>();
|
||||
@@ -51,13 +48,12 @@ public class ReferenceCountedTrigger {
|
||||
}
|
||||
};
|
||||
|
||||
public ReferenceCountedTrigger(Context context) {
|
||||
this(context, null, null, null);
|
||||
public ReferenceCountedTrigger() {
|
||||
this(null, null, null);
|
||||
}
|
||||
|
||||
public ReferenceCountedTrigger(Context context, Runnable firstIncRunnable,
|
||||
Runnable lastDecRunnable, Runnable errorRunanable) {
|
||||
mContext = context;
|
||||
public ReferenceCountedTrigger(Runnable firstIncRunnable, Runnable lastDecRunnable,
|
||||
Runnable errorRunanable) {
|
||||
if (firstIncRunnable != null) mFirstIncRunnables.add(firstIncRunnable);
|
||||
if (lastDecRunnable != null) mLastDecRunnables.add(lastDecRunnable);
|
||||
mErrorRunnable = errorRunanable;
|
||||
@@ -81,22 +77,14 @@ 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 */
|
||||
public void decrement() {
|
||||
mCount--;
|
||||
if (mCount == 0 && !mLastDecRunnables.isEmpty()) {
|
||||
int numRunnables = mLastDecRunnables.size();
|
||||
for (int i = 0; i < numRunnables; i++) {
|
||||
mLastDecRunnables.get(i).run();
|
||||
}
|
||||
if (mCount == 0) {
|
||||
flushLastDecrementRunnables();
|
||||
} else if (mCount < 0) {
|
||||
if (mErrorRunnable != null) {
|
||||
mErrorRunnable.run();
|
||||
@@ -106,6 +94,19 @@ public class ReferenceCountedTrigger {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs and clears all the last-decrement runnables now.
|
||||
*/
|
||||
public void flushLastDecrementRunnables() {
|
||||
if (!mLastDecRunnables.isEmpty()) {
|
||||
int numRunnables = mLastDecRunnables.size();
|
||||
for (int i = 0; i < numRunnables; i++) {
|
||||
mLastDecRunnables.get(i).run();
|
||||
}
|
||||
}
|
||||
mLastDecRunnables.clear();
|
||||
}
|
||||
|
||||
/** Convenience method to decrement this trigger as a runnable. */
|
||||
public Runnable decrementAsRunnable() {
|
||||
return mDecrementRunnable;
|
||||
|
||||
@@ -43,6 +43,7 @@ import android.graphics.Point;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
@@ -572,7 +573,7 @@ public class SystemServicesProxy {
|
||||
* Returns the activity icon for the ActivityInfo for a user, badging if
|
||||
* necessary.
|
||||
*/
|
||||
public Drawable getActivityIcon(ActivityInfo info, int userId) {
|
||||
public Drawable getBadgedActivityIcon(ActivityInfo info, int userId) {
|
||||
if (mPm == null) return null;
|
||||
|
||||
// If we are mocking, then return a mock label
|
||||
@@ -584,10 +585,32 @@ public class SystemServicesProxy {
|
||||
return getBadgedIcon(icon, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the task description icon, loading and badging it if it necessary.
|
||||
*/
|
||||
public Drawable getBadgedTaskDescriptionIcon(ActivityManager.TaskDescription taskDescription,
|
||||
int userId, Resources res) {
|
||||
|
||||
// If we are mocking, then return a mock label
|
||||
if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
|
||||
return new ColorDrawable(0xFF666666);
|
||||
}
|
||||
|
||||
Bitmap tdIcon = taskDescription.getInMemoryIcon();
|
||||
if (tdIcon == null) {
|
||||
tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon(
|
||||
taskDescription.getIconFilename(), userId);
|
||||
}
|
||||
if (tdIcon != null) {
|
||||
return getBadgedIcon(new BitmapDrawable(res, tdIcon), userId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given icon for a user, badging if necessary.
|
||||
*/
|
||||
public Drawable getBadgedIcon(Drawable icon, int userId) {
|
||||
private Drawable getBadgedIcon(Drawable icon, int userId) {
|
||||
if (userId != UserHandle.myUserId()) {
|
||||
icon = mPm.getUserBadgedIcon(icon, new UserHandle(userId));
|
||||
}
|
||||
@@ -597,7 +620,7 @@ public class SystemServicesProxy {
|
||||
/**
|
||||
* Returns the given label for a user, badging if necessary.
|
||||
*/
|
||||
public String getBadgedLabel(String label, int userId) {
|
||||
private String getBadgedLabel(String label, int userId) {
|
||||
if (userId != UserHandle.myUserId()) {
|
||||
label = mPm.getUserBadgedLabel(label, new UserHandle(userId)).toString();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import android.util.Log;
|
||||
import com.android.systemui.Prefs;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.RecentsConfiguration;
|
||||
import com.android.systemui.recents.RecentsDebugFlags;
|
||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -47,9 +46,6 @@ import java.util.List;
|
||||
*/
|
||||
public class RecentsTaskLoadPlan {
|
||||
|
||||
private static String TAG = "RecentsTaskLoadPlan";
|
||||
private static boolean DEBUG = false;
|
||||
|
||||
private static int MIN_NUM_TASKS = 5;
|
||||
private static int SESSION_BEGIN_TIME = 1000 /* ms/s */ * 60 /* s/min */ * 60 /* min/hr */ *
|
||||
6 /* hrs */;
|
||||
@@ -107,13 +103,6 @@ public class RecentsTaskLoadPlan {
|
||||
|
||||
// Since the raw tasks are given in most-recent to least-recent order, we need to reverse it
|
||||
Collections.reverse(mRawTasks);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "preloadRawTasks, tasks: " + mRawTasks.size());
|
||||
for (ActivityManager.RecentTaskInfo info : mRawTasks) {
|
||||
Log.d(TAG, " " + info.baseIntent + ", " + info.lastActiveTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,8 +115,6 @@ public class RecentsTaskLoadPlan {
|
||||
* - least-recent to most-recent freeform tasks
|
||||
*/
|
||||
public synchronized void preloadPlan(RecentsTaskLoader loader, boolean isTopTaskHome) {
|
||||
if (DEBUG) Log.d(TAG, "preloadPlan");
|
||||
|
||||
RecentsConfiguration config = Recents.getConfiguration();
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
Resources res = mContext.getResources();
|
||||
@@ -149,38 +136,26 @@ public class RecentsTaskLoadPlan {
|
||||
|
||||
// This task is only shown in the stack if it statisfies the historical time or min
|
||||
// number of tasks constraints. Freeform tasks are also always shown.
|
||||
boolean isStackTask = true;
|
||||
boolean isFreeformTask = SystemServicesProxy.isFreeformStack(t.stackId);
|
||||
isStackTask = isFreeformTask || (!isHistoricalTask(t) ||
|
||||
(t.lastActiveTime >= lastStackActiveTime &&
|
||||
i >= (taskCount - MIN_NUM_TASKS)));
|
||||
boolean isStackTask = isFreeformTask || (!isHistoricalTask(t) ||
|
||||
(t.lastActiveTime >= lastStackActiveTime && i >= (taskCount - MIN_NUM_TASKS)));
|
||||
if (isStackTask && newLastStackActiveTime < 0) {
|
||||
newLastStackActiveTime = t.lastActiveTime;
|
||||
}
|
||||
|
||||
// Load the label, icon, and color
|
||||
String activityLabel = loader.getAndUpdateActivityLabel(taskKey, t.taskDescription,
|
||||
ssp);
|
||||
String contentDescription = loader.getAndUpdateContentDescription(taskKey,
|
||||
activityLabel, ssp, res);
|
||||
Drawable activityIcon = isStackTask
|
||||
? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, ssp, res, false)
|
||||
// Load the title, icon, and color
|
||||
String title = loader.getAndUpdateActivityTitle(taskKey, t.taskDescription);
|
||||
String contentDescription = loader.getAndUpdateContentDescription(taskKey, title, res);
|
||||
Drawable icon = isStackTask
|
||||
? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, res, false)
|
||||
: null;
|
||||
Bitmap thumbnail = loader.getAndUpdateThumbnail(taskKey, false);
|
||||
int activityColor = loader.getActivityPrimaryColor(t.taskDescription);
|
||||
|
||||
Bitmap icon = t.taskDescription != null
|
||||
? t.taskDescription.getInMemoryIcon() : null;
|
||||
String iconFilename = t.taskDescription != null
|
||||
? t.taskDescription.getIconFilename() : null;
|
||||
|
||||
// Add the task to the stack
|
||||
Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, activityLabel,
|
||||
contentDescription, activityIcon, activityColor, (i == (taskCount - 1)),
|
||||
config.lockToAppEnabled, !isStackTask, icon, iconFilename, t.bounds);
|
||||
task.thumbnail = loader.getAndUpdateThumbnail(taskKey, ssp, false);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, activityLabel + " bounds: " + t.bounds);
|
||||
}
|
||||
Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon,
|
||||
thumbnail, title, contentDescription, activityColor, !isStackTask,
|
||||
(i == (taskCount - 1)), config.lockToAppEnabled, t.bounds, t.taskDescription);
|
||||
|
||||
allTasks.add(task);
|
||||
}
|
||||
@@ -200,19 +175,13 @@ public class RecentsTaskLoadPlan {
|
||||
*/
|
||||
public synchronized void executePlan(Options opts, RecentsTaskLoader loader,
|
||||
TaskResourceLoadQueue loadQueue) {
|
||||
if (DEBUG) Log.d(TAG, "executePlan, # tasks: " + opts.numVisibleTasks +
|
||||
", # thumbnails: " + opts.numVisibleTaskThumbnails +
|
||||
", running task id: " + opts.runningTaskId);
|
||||
|
||||
RecentsConfiguration config = Recents.getConfiguration();
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
Resources res = mContext.getResources();
|
||||
|
||||
// Iterate through each of the tasks and load them according to the load conditions.
|
||||
ArrayList<Task> tasks = mStack.getStackTasks();
|
||||
int taskCount = tasks.size();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
|
||||
Task task = tasks.get(i);
|
||||
Task.TaskKey taskKey = task.key;
|
||||
|
||||
@@ -226,17 +195,15 @@ public class RecentsTaskLoadPlan {
|
||||
}
|
||||
|
||||
if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
|
||||
if (task.activityIcon == null) {
|
||||
if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
|
||||
task.activityIcon = loader.getAndUpdateActivityIcon(taskKey, t.taskDescription,
|
||||
ssp, res, true);
|
||||
if (task.icon == null) {
|
||||
task.icon = loader.getAndUpdateActivityIcon(taskKey, task.taskDescription,
|
||||
res, true);
|
||||
}
|
||||
}
|
||||
if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
|
||||
if (task.thumbnail == null || isRunningTask) {
|
||||
if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
|
||||
if (config.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
|
||||
task.thumbnail = loader.getAndUpdateThumbnail(taskKey, ssp, true);
|
||||
task.thumbnail = loader.getAndUpdateThumbnail(taskKey, true);
|
||||
} else if (config.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
|
||||
loadQueue.addTask(task);
|
||||
}
|
||||
|
||||
@@ -93,23 +93,23 @@ class BackgroundTaskLoader implements Runnable {
|
||||
Handler mMainThreadHandler;
|
||||
|
||||
TaskResourceLoadQueue mLoadQueue;
|
||||
TaskKeyLruCache<Drawable> mApplicationIconCache;
|
||||
TaskKeyLruCache<Drawable> mIconCache;
|
||||
TaskKeyLruCache<Bitmap> mThumbnailCache;
|
||||
Bitmap mDefaultThumbnail;
|
||||
BitmapDrawable mDefaultApplicationIcon;
|
||||
BitmapDrawable mDefaultIcon;
|
||||
|
||||
boolean mCancelled;
|
||||
boolean mWaitingOnLoadQueue;
|
||||
|
||||
/** Constructor, creates a new loading thread that loads task resources in the background */
|
||||
public BackgroundTaskLoader(TaskResourceLoadQueue loadQueue,
|
||||
TaskKeyLruCache<Drawable> applicationIconCache, TaskKeyLruCache<Bitmap> thumbnailCache,
|
||||
Bitmap defaultThumbnail, BitmapDrawable defaultApplicationIcon) {
|
||||
TaskKeyLruCache<Drawable> iconCache, TaskKeyLruCache<Bitmap> thumbnailCache,
|
||||
Bitmap defaultThumbnail, BitmapDrawable defaultIcon) {
|
||||
mLoadQueue = loadQueue;
|
||||
mApplicationIconCache = applicationIconCache;
|
||||
mIconCache = iconCache;
|
||||
mThumbnailCache = thumbnailCache;
|
||||
mDefaultThumbnail = defaultThumbnail;
|
||||
mDefaultApplicationIcon = defaultApplicationIcon;
|
||||
mDefaultIcon = defaultIcon;
|
||||
mMainThreadHandler = new Handler();
|
||||
mLoadThread = new HandlerThread("Recents-TaskResourceLoader",
|
||||
android.os.Process.THREAD_PRIORITY_BACKGROUND);
|
||||
@@ -163,30 +163,30 @@ class BackgroundTaskLoader implements Runnable {
|
||||
// Load the next item from the queue
|
||||
final Task t = mLoadQueue.nextTask();
|
||||
if (t != null) {
|
||||
Drawable cachedIcon = mApplicationIconCache.get(t.key);
|
||||
Drawable cachedIcon = mIconCache.get(t.key);
|
||||
Bitmap cachedThumbnail = mThumbnailCache.get(t.key);
|
||||
|
||||
// Load the application icon if it is stale or we haven't cached one yet
|
||||
// Load the icon if it is stale or we haven't cached one yet
|
||||
if (cachedIcon == null) {
|
||||
cachedIcon = getTaskDescriptionIcon(t.key, t.icon, t.iconFilename, ssp,
|
||||
mContext.getResources());
|
||||
cachedIcon = ssp.getBadgedTaskDescriptionIcon(t.taskDescription,
|
||||
t.key.userId, mContext.getResources());
|
||||
|
||||
if (cachedIcon == null) {
|
||||
ActivityInfo info = ssp.getActivityInfo(
|
||||
t.key.getComponent(), t.key.userId);
|
||||
if (info != null) {
|
||||
if (DEBUG) Log.d(TAG, "Loading icon: " + t.key);
|
||||
cachedIcon = ssp.getActivityIcon(info, t.key.userId);
|
||||
cachedIcon = ssp.getBadgedActivityIcon(info, t.key.userId);
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedIcon == null) {
|
||||
cachedIcon = mDefaultApplicationIcon;
|
||||
cachedIcon = mDefaultIcon;
|
||||
}
|
||||
|
||||
// At this point, even if we can't load the icon, we will set the
|
||||
// default icon.
|
||||
mApplicationIconCache.put(t.key, cachedIcon);
|
||||
mIconCache.put(t.key, cachedIcon);
|
||||
}
|
||||
// Load the thumbnail if it is stale or we haven't cached one yet
|
||||
if (cachedThumbnail == null) {
|
||||
@@ -234,25 +234,6 @@ class BackgroundTaskLoader implements Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Drawable getTaskDescriptionIcon(Task.TaskKey taskKey, Bitmap iconBitmap, String iconFilename,
|
||||
SystemServicesProxy ssp, Resources res) {
|
||||
Bitmap tdIcon = null;
|
||||
if (iconBitmap != null) {
|
||||
tdIcon = iconBitmap;
|
||||
} else {
|
||||
try {
|
||||
tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon(iconFilename,
|
||||
taskKey.userId);
|
||||
} catch (Exception e) {
|
||||
// TODO: Investigate for b/26221779
|
||||
}
|
||||
}
|
||||
if (tdIcon != null) {
|
||||
return ssp.getBadgedIcon(new BitmapDrawable(res, tdIcon), taskKey.userId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,7 +250,7 @@ public class RecentsTaskLoader {
|
||||
// active time. Instead, we rely on the RecentsPackageMonitor to keep us informed whenever a
|
||||
// package in the cache has been updated, so that we may remove it.
|
||||
private final LruCache<ComponentName, ActivityInfo> mActivityInfoCache;
|
||||
private final TaskKeyLruCache<Drawable> mApplicationIconCache;
|
||||
private final TaskKeyLruCache<Drawable> mIconCache;
|
||||
private final TaskKeyLruCache<Bitmap> mThumbnailCache;
|
||||
private final TaskKeyLruCache<String> mActivityLabelCache;
|
||||
private final TaskKeyLruCache<String> mContentDescriptionCache;
|
||||
@@ -282,7 +263,7 @@ public class RecentsTaskLoader {
|
||||
private int mNumVisibleThumbnailsLoaded;
|
||||
|
||||
int mDefaultTaskBarBackgroundColor;
|
||||
BitmapDrawable mDefaultApplicationIcon;
|
||||
BitmapDrawable mDefaultIcon;
|
||||
Bitmap mDefaultThumbnail;
|
||||
|
||||
public RecentsTaskLoader(Context context) {
|
||||
@@ -302,22 +283,22 @@ public class RecentsTaskLoader {
|
||||
mDefaultThumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
|
||||
mDefaultThumbnail.setHasAlpha(false);
|
||||
mDefaultThumbnail.eraseColor(0xFFffffff);
|
||||
mDefaultApplicationIcon = new BitmapDrawable(context.getResources(), icon);
|
||||
mDefaultIcon = new BitmapDrawable(context.getResources(), icon);
|
||||
|
||||
// Initialize the proxy, cache and loaders
|
||||
int numRecentTasks = ActivityManager.getMaxRecentTasksStatic();
|
||||
mLoadQueue = new TaskResourceLoadQueue();
|
||||
mApplicationIconCache = new TaskKeyLruCache<>(iconCacheSize);
|
||||
mIconCache = new TaskKeyLruCache<>(iconCacheSize);
|
||||
mThumbnailCache = new TaskKeyLruCache<>(thumbnailCacheSize);
|
||||
mActivityLabelCache = new TaskKeyLruCache<>(numRecentTasks);
|
||||
mContentDescriptionCache = new TaskKeyLruCache<>(numRecentTasks);
|
||||
mActivityInfoCache = new LruCache(numRecentTasks);
|
||||
mLoader = new BackgroundTaskLoader(mLoadQueue, mApplicationIconCache, mThumbnailCache,
|
||||
mDefaultThumbnail, mDefaultApplicationIcon);
|
||||
mLoader = new BackgroundTaskLoader(mLoadQueue, mIconCache, mThumbnailCache,
|
||||
mDefaultThumbnail, mDefaultIcon);
|
||||
}
|
||||
|
||||
/** Returns the size of the app icon cache. */
|
||||
public int getApplicationIconCacheSize() {
|
||||
public int getIconCacheSize() {
|
||||
return mMaxIconCacheSize;
|
||||
}
|
||||
|
||||
@@ -355,33 +336,33 @@ public class RecentsTaskLoader {
|
||||
|
||||
/** Acquires the task resource data directly from the pool. */
|
||||
public void loadTaskData(Task t) {
|
||||
Drawable applicationIcon = mApplicationIconCache.getAndInvalidateIfModified(t.key);
|
||||
Drawable icon = mIconCache.getAndInvalidateIfModified(t.key);
|
||||
Bitmap thumbnail = mThumbnailCache.getAndInvalidateIfModified(t.key);
|
||||
|
||||
// Grab the thumbnail/icon from the cache, if either don't exist, then trigger a reload and
|
||||
// use the default assets in their place until they load
|
||||
boolean requiresLoad = (applicationIcon == null) || (thumbnail == null);
|
||||
applicationIcon = applicationIcon != null ? applicationIcon : mDefaultApplicationIcon;
|
||||
boolean requiresLoad = (icon == null) || (thumbnail == null);
|
||||
icon = icon != null ? icon : mDefaultIcon;
|
||||
if (requiresLoad) {
|
||||
mLoadQueue.addTask(t);
|
||||
}
|
||||
t.notifyTaskDataLoaded(thumbnail == mDefaultThumbnail ? null : thumbnail, applicationIcon);
|
||||
t.notifyTaskDataLoaded(thumbnail == mDefaultThumbnail ? null : thumbnail, icon);
|
||||
}
|
||||
|
||||
/** Releases the task resource data back into the pool. */
|
||||
public void unloadTaskData(Task t) {
|
||||
mLoadQueue.removeTask(t);
|
||||
t.notifyTaskDataUnloaded(null, mDefaultApplicationIcon);
|
||||
t.notifyTaskDataUnloaded(null, mDefaultIcon);
|
||||
}
|
||||
|
||||
/** Completely removes the resource data from the pool. */
|
||||
public void deleteTaskData(Task t, boolean notifyTaskDataUnloaded) {
|
||||
mLoadQueue.removeTask(t);
|
||||
mThumbnailCache.remove(t.key);
|
||||
mApplicationIconCache.remove(t.key);
|
||||
mIconCache.remove(t.key);
|
||||
mActivityInfoCache.remove(t.key.getComponent());
|
||||
if (notifyTaskDataUnloaded) {
|
||||
t.notifyTaskDataUnloaded(null, mDefaultApplicationIcon);
|
||||
t.notifyTaskDataUnloaded(null, mDefaultIcon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,14 +384,14 @@ public class RecentsTaskLoader {
|
||||
} else if (config.svelteLevel >= RecentsConfiguration.SVELTE_DISABLE_CACHE) {
|
||||
mThumbnailCache.evictAll();
|
||||
}
|
||||
mApplicationIconCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
|
||||
mIconCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
|
||||
mMaxIconCacheSize / 2));
|
||||
break;
|
||||
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
|
||||
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
|
||||
// We are leaving recents, so trim the data a bit
|
||||
mThumbnailCache.trimToSize(Math.max(1, mMaxThumbnailCacheSize / 2));
|
||||
mApplicationIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 2));
|
||||
mIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 2));
|
||||
mActivityInfoCache.trimToSize(Math.max(1,
|
||||
ActivityManager.getMaxRecentTasksStatic() / 2));
|
||||
break;
|
||||
@@ -418,7 +399,7 @@ public class RecentsTaskLoader {
|
||||
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
|
||||
// We are going to be low on memory
|
||||
mThumbnailCache.trimToSize(Math.max(1, mMaxThumbnailCacheSize / 4));
|
||||
mApplicationIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 4));
|
||||
mIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 4));
|
||||
mActivityInfoCache.trimToSize(Math.max(1,
|
||||
ActivityManager.getMaxRecentTasksStatic() / 4));
|
||||
break;
|
||||
@@ -426,7 +407,7 @@ public class RecentsTaskLoader {
|
||||
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
|
||||
// We are low on memory, so release everything
|
||||
mThumbnailCache.evictAll();
|
||||
mApplicationIconCache.evictAll();
|
||||
mIconCache.evictAll();
|
||||
mActivityInfoCache.evictAll();
|
||||
// The cache is small, only clear the label cache when we are critical
|
||||
mActivityLabelCache.evictAll();
|
||||
@@ -440,8 +421,9 @@ public class RecentsTaskLoader {
|
||||
/**
|
||||
* Returns the cached task label if the task key is not expired, updating the cache if it is.
|
||||
*/
|
||||
String getAndUpdateActivityLabel(Task.TaskKey taskKey, ActivityManager.TaskDescription td,
|
||||
SystemServicesProxy ssp) {
|
||||
String getAndUpdateActivityTitle(Task.TaskKey taskKey, ActivityManager.TaskDescription td) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
|
||||
// Return the task description label if it exists
|
||||
if (td != null && td.getLabel() != null) {
|
||||
return td.getLabel();
|
||||
@@ -452,7 +434,7 @@ public class RecentsTaskLoader {
|
||||
return label;
|
||||
}
|
||||
// All short paths failed, load the label from the activity info and cache it
|
||||
ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey, ssp);
|
||||
ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
|
||||
if (activityInfo != null) {
|
||||
label = ssp.getActivityLabel(activityInfo);
|
||||
mActivityLabelCache.put(taskKey, label);
|
||||
@@ -468,7 +450,9 @@ public class RecentsTaskLoader {
|
||||
* cache if it is.
|
||||
*/
|
||||
String getAndUpdateContentDescription(Task.TaskKey taskKey, String activityLabel,
|
||||
SystemServicesProxy ssp, Resources res) {
|
||||
Resources res) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
|
||||
// Return the cached content description if it exists
|
||||
String label = mContentDescriptionCache.getAndInvalidateIfModified(taskKey);
|
||||
if (label != null) {
|
||||
@@ -493,28 +477,29 @@ public class RecentsTaskLoader {
|
||||
* Returns the cached task icon if the task key is not expired, updating the cache if it is.
|
||||
*/
|
||||
Drawable getAndUpdateActivityIcon(Task.TaskKey taskKey, ActivityManager.TaskDescription td,
|
||||
SystemServicesProxy ssp, Resources res, boolean loadIfNotCached) {
|
||||
Resources res, boolean loadIfNotCached) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
|
||||
// Return the cached activity icon if it exists
|
||||
Drawable icon = mApplicationIconCache.getAndInvalidateIfModified(taskKey);
|
||||
Drawable icon = mIconCache.getAndInvalidateIfModified(taskKey);
|
||||
if (icon != null) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
if (loadIfNotCached) {
|
||||
// Return and cache the task description icon if it exists
|
||||
icon = mLoader.getTaskDescriptionIcon(taskKey, td.getInMemoryIcon(),
|
||||
td.getIconFilename(), ssp, res);
|
||||
icon = ssp.getBadgedTaskDescriptionIcon(td, taskKey.userId, res);
|
||||
if (icon != null) {
|
||||
mApplicationIconCache.put(taskKey, icon);
|
||||
mIconCache.put(taskKey, icon);
|
||||
return icon;
|
||||
}
|
||||
|
||||
// Load the icon from the activity info and cache it
|
||||
ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey, ssp);
|
||||
ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
|
||||
if (activityInfo != null) {
|
||||
icon = ssp.getActivityIcon(activityInfo, taskKey.userId);
|
||||
icon = ssp.getBadgedActivityIcon(activityInfo, taskKey.userId);
|
||||
if (icon != null) {
|
||||
mApplicationIconCache.put(taskKey, icon);
|
||||
mIconCache.put(taskKey, icon);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
@@ -526,8 +511,9 @@ public class RecentsTaskLoader {
|
||||
/**
|
||||
* Returns the cached thumbnail if the task key is not expired, updating the cache if it is.
|
||||
*/
|
||||
Bitmap getAndUpdateThumbnail(Task.TaskKey taskKey, SystemServicesProxy ssp,
|
||||
boolean loadIfNotCached) {
|
||||
Bitmap getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
|
||||
// Return the cached thumbnail if it exists
|
||||
Bitmap thumbnail = mThumbnailCache.getAndInvalidateIfModified(taskKey);
|
||||
if (thumbnail != null) {
|
||||
@@ -550,7 +536,8 @@ public class RecentsTaskLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the task's primary color.
|
||||
* Returns the task's primary color if possible, defaulting to the default color if there is
|
||||
* no specified primary color.
|
||||
*/
|
||||
int getActivityPrimaryColor(ActivityManager.TaskDescription td) {
|
||||
if (td != null && td.getPrimaryColor() != 0) {
|
||||
@@ -563,7 +550,8 @@ public class RecentsTaskLoader {
|
||||
* Returns the activity info for the given task key, retrieving one from the system if the
|
||||
* task key is expired.
|
||||
*/
|
||||
private ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey, SystemServicesProxy ssp) {
|
||||
private ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
ComponentName cn = taskKey.getComponent();
|
||||
ActivityInfo activityInfo = mActivityInfoCache.get(cn);
|
||||
if (activityInfo == null) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.recents.model;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -92,24 +93,46 @@ public class Task {
|
||||
}
|
||||
|
||||
public TaskKey key;
|
||||
|
||||
/**
|
||||
* The group will be computed separately from the initialization of the task
|
||||
*/
|
||||
public TaskGrouping group;
|
||||
// The taskAffiliationId is the task id of the parent task or itself if it is not affiliated with any task
|
||||
public int taskAffiliationId;
|
||||
public int taskAffiliationColor;
|
||||
public boolean isLaunchTarget;
|
||||
public Drawable applicationIcon;
|
||||
public Drawable activityIcon;
|
||||
/**
|
||||
* The affiliationTaskId is the task id of the parent task or itself if it is not affiliated
|
||||
* with any task.
|
||||
*/
|
||||
public int affiliationTaskId;
|
||||
public int affiliationColor;
|
||||
|
||||
/**
|
||||
* The icon is the task description icon (if provided), which falls back to the activity icon,
|
||||
* which can then fall back to the application icon.
|
||||
*/
|
||||
public Drawable icon;
|
||||
public Bitmap thumbnail;
|
||||
public String title;
|
||||
public String contentDescription;
|
||||
public String activityLabel;
|
||||
public int colorPrimary;
|
||||
public boolean useLightOnPrimaryColor;
|
||||
public Bitmap thumbnail;
|
||||
|
||||
/**
|
||||
* The bounds of the task, used only if it is a freeform task.
|
||||
*/
|
||||
public Rect bounds;
|
||||
|
||||
/**
|
||||
* The task description for this task, only used to reload task icons.
|
||||
*/
|
||||
public ActivityManager.TaskDescription taskDescription;
|
||||
|
||||
/**
|
||||
* The state isLaunchTarget will be set for the correct task upon launching Recents.
|
||||
*/
|
||||
public boolean isLaunchTarget;
|
||||
public boolean isHistorical;
|
||||
public boolean lockToThisTask;
|
||||
public boolean lockToTaskEnabled;
|
||||
public boolean isHistorical;
|
||||
public Bitmap icon;
|
||||
public String iconFilename;
|
||||
public Rect bounds;
|
||||
|
||||
private ArrayList<TaskCallbacks> mCallbacks = new ArrayList<>();
|
||||
|
||||
@@ -117,45 +140,46 @@ public class Task {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public Task(TaskKey key, int taskAffiliation, int taskAffiliationColor,
|
||||
String activityTitle, String contentDescription, Drawable activityIcon,
|
||||
int colorPrimary, boolean lockToThisTask, boolean lockToTaskEnabled,
|
||||
boolean isHistorical, Bitmap icon, String iconFilename, Rect bounds) {
|
||||
boolean isInAffiliationGroup = (taskAffiliation != key.id);
|
||||
boolean hasAffiliationGroupColor = isInAffiliationGroup && (taskAffiliationColor != 0);
|
||||
public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon,
|
||||
Bitmap thumbnail, String title, String contentDescription, int colorPrimary,
|
||||
boolean isHistorical, boolean lockToThisTask, boolean lockToTaskEnabled,
|
||||
Rect bounds, ActivityManager.TaskDescription taskDescription) {
|
||||
boolean isInAffiliationGroup = (affiliationTaskId != key.id);
|
||||
boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0);
|
||||
this.key = key;
|
||||
this.taskAffiliationId = taskAffiliation;
|
||||
this.taskAffiliationColor = taskAffiliationColor;
|
||||
this.activityLabel = activityTitle;
|
||||
this.affiliationTaskId = affiliationTaskId;
|
||||
this.affiliationColor = affiliationColor;
|
||||
this.icon = icon;
|
||||
this.thumbnail = thumbnail;
|
||||
this.title = title;
|
||||
this.contentDescription = contentDescription;
|
||||
this.activityIcon = activityIcon;
|
||||
this.colorPrimary = hasAffiliationGroupColor ? taskAffiliationColor : colorPrimary;
|
||||
this.colorPrimary = hasAffiliationGroupColor ? affiliationColor : colorPrimary;
|
||||
this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary,
|
||||
Color.WHITE) > 3f;
|
||||
this.bounds = bounds;
|
||||
this.taskDescription = taskDescription;
|
||||
this.isHistorical = isHistorical;
|
||||
this.lockToThisTask = lockToTaskEnabled && lockToThisTask;
|
||||
this.lockToTaskEnabled = lockToTaskEnabled;
|
||||
this.isHistorical = isHistorical;
|
||||
this.icon = icon;
|
||||
this.iconFilename = iconFilename;
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
/** Copies the other task. */
|
||||
public void copyFrom(Task o) {
|
||||
this.key = o.key;
|
||||
this.taskAffiliationId = o.taskAffiliationId;
|
||||
this.taskAffiliationColor = o.taskAffiliationColor;
|
||||
this.activityLabel = o.activityLabel;
|
||||
this.group = o.group;
|
||||
this.affiliationTaskId = o.affiliationTaskId;
|
||||
this.affiliationColor = o.affiliationColor;
|
||||
this.icon = o.icon;
|
||||
this.thumbnail = o.thumbnail;
|
||||
this.title = o.title;
|
||||
this.contentDescription = o.contentDescription;
|
||||
this.activityIcon = o.activityIcon;
|
||||
this.colorPrimary = o.colorPrimary;
|
||||
this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
|
||||
this.bounds = o.bounds;
|
||||
this.isLaunchTarget = o.isLaunchTarget;
|
||||
this.isHistorical = o.isHistorical;
|
||||
this.lockToThisTask = o.lockToThisTask;
|
||||
this.lockToTaskEnabled = o.lockToTaskEnabled;
|
||||
this.isHistorical = o.isHistorical;
|
||||
this.icon = o.icon;
|
||||
this.iconFilename = o.iconFilename;
|
||||
this.bounds = o.bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +224,7 @@ public class Task {
|
||||
|
||||
/** Notifies the callback listeners that this task has been loaded */
|
||||
public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon) {
|
||||
this.applicationIcon = applicationIcon;
|
||||
this.icon = applicationIcon;
|
||||
this.thumbnail = thumbnail;
|
||||
int callbackCount = mCallbacks.size();
|
||||
for (int i = 0; i < callbackCount; i++) {
|
||||
@@ -210,7 +234,7 @@ public class Task {
|
||||
|
||||
/** Notifies the callback listeners that this task has been unloaded */
|
||||
public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultApplicationIcon) {
|
||||
applicationIcon = defaultApplicationIcon;
|
||||
icon = defaultApplicationIcon;
|
||||
thumbnail = defaultThumbnail;
|
||||
int callbackCount = mCallbacks.size();
|
||||
for (int i = 0; i < callbackCount; i++) {
|
||||
@@ -222,7 +246,7 @@ public class Task {
|
||||
* Returns whether this task is affiliated with another task.
|
||||
*/
|
||||
public boolean isAffiliatedTask() {
|
||||
return key.id != taskAffiliationId;
|
||||
return key.id != affiliationTaskId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -354,7 +354,7 @@ public class TaskStack {
|
||||
if (t.isAffiliatedTask()) {
|
||||
// If this task is affiliated with another parent in the stack, then the historical state of this
|
||||
// task depends on the state of the parent task
|
||||
Task parentTask = taskIdMap.get(t.taskAffiliationId);
|
||||
Task parentTask = taskIdMap.get(t.affiliationTaskId);
|
||||
if (parentTask != null) {
|
||||
t = parentTask;
|
||||
}
|
||||
@@ -368,7 +368,7 @@ public class TaskStack {
|
||||
if (t.isAffiliatedTask()) {
|
||||
// If this task is affiliated with another parent in the stack, then the historical state of this
|
||||
// task depends on the state of the parent task
|
||||
Task parentTask = taskIdMap.get(t.taskAffiliationId);
|
||||
Task parentTask = taskIdMap.get(t.affiliationTaskId);
|
||||
if (parentTask != null) {
|
||||
t = parentTask;
|
||||
}
|
||||
@@ -716,7 +716,7 @@ public class TaskStack {
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
Task t = tasks.get(i);
|
||||
TaskGrouping group;
|
||||
int affiliation = t.taskAffiliationId > 0 ? t.taskAffiliationId :
|
||||
int affiliation = t.affiliationTaskId > 0 ? t.affiliationTaskId :
|
||||
IndividualTaskIdOffset + t.key.id;
|
||||
if (mAffinitiesGroups.containsKey(affiliation)) {
|
||||
group = getGroupWithAffiliation(affiliation);
|
||||
@@ -737,7 +737,7 @@ public class TaskStack {
|
||||
// Ignore the groups that only have one task
|
||||
if (taskCount <= 1) continue;
|
||||
// Calculate the group color distribution
|
||||
int affiliationColor = tasksMap.get(group.mTaskKeys.get(0)).taskAffiliationColor;
|
||||
int affiliationColor = tasksMap.get(group.mTaskKeys.get(0)).affiliationColor;
|
||||
float alphaStep = (1f - minAlpha) / taskCount;
|
||||
float alpha = 1f;
|
||||
for (int j = 0; j < taskCount; j++) {
|
||||
|
||||
@@ -157,7 +157,7 @@ public class RecentsTransitionHelper {
|
||||
ActivityOptions opts, IAppTransitionAnimationSpecsFuture transitionFuture,
|
||||
final ActivityOptions.OnAnimationStartedListener animStartedListener) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
if (ssp.startActivityFromRecents(mContext, task.key.id, task.activityLabel, opts)) {
|
||||
if (ssp.startActivityFromRecents(mContext, task.key.id, task.title, opts)) {
|
||||
// Keep track of the index of the task launch
|
||||
int taskIndexFromFront = 0;
|
||||
int taskIndex = stack.indexOfStackTask(task);
|
||||
|
||||
@@ -132,10 +132,7 @@ public class RecentsView extends FrameLayout {
|
||||
mHistoryButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ReferenceCountedTrigger postHideStackAnimationTrigger = new ReferenceCountedTrigger(v.getContext());
|
||||
postHideStackAnimationTrigger.increment();
|
||||
EventBus.getDefault().send(new ShowHistoryEvent(postHideStackAnimationTrigger));
|
||||
postHideStackAnimationTrigger.decrement();
|
||||
EventBus.getDefault().send(new ShowHistoryEvent());
|
||||
}
|
||||
});
|
||||
addView(mHistoryButton);
|
||||
@@ -576,8 +573,8 @@ public class RecentsView extends FrameLayout {
|
||||
public final void onBusEvent(ShowHistoryEvent event) {
|
||||
// Hide the history button when the history view is shown
|
||||
hideHistoryButton(getResources().getInteger(R.integer.recents_history_transition_duration),
|
||||
event.postHideStackAnimationTrigger);
|
||||
event.postHideStackAnimationTrigger.addLastDecrementRunnable(new Runnable() {
|
||||
event.getAnimationTrigger());
|
||||
event.addPostAnimationCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setAlpha(0f);
|
||||
@@ -589,7 +586,7 @@ public class RecentsView extends FrameLayout {
|
||||
// Show the history button when the history view is hidden
|
||||
setAlpha(1f);
|
||||
showHistoryButton(getResources().getInteger(R.integer.recents_history_transition_duration),
|
||||
event.postHideHistoryAnimationTrigger);
|
||||
event.getAnimationTrigger());
|
||||
}
|
||||
|
||||
public final void onBusEvent(ShowHistoryButtonEvent event) {
|
||||
@@ -609,10 +606,9 @@ public class RecentsView extends FrameLayout {
|
||||
* Shows the history button.
|
||||
*/
|
||||
private void showHistoryButton(final int duration) {
|
||||
ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger(getContext());
|
||||
postAnimationTrigger.increment();
|
||||
ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
|
||||
showHistoryButton(duration, postAnimationTrigger);
|
||||
postAnimationTrigger.decrement();
|
||||
postAnimationTrigger.flushLastDecrementRunnables();
|
||||
}
|
||||
|
||||
private void showHistoryButton(final int duration,
|
||||
@@ -638,10 +634,9 @@ public class RecentsView extends FrameLayout {
|
||||
* Hides the history button.
|
||||
*/
|
||||
private void hideHistoryButton(int duration) {
|
||||
ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger(getContext());
|
||||
postAnimationTrigger.increment();
|
||||
ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
|
||||
hideHistoryButton(duration, postAnimationTrigger);
|
||||
postAnimationTrigger.decrement();
|
||||
postAnimationTrigger.flushLastDecrementRunnables();
|
||||
}
|
||||
|
||||
private void hideHistoryButton(int duration,
|
||||
|
||||
@@ -188,12 +188,8 @@ public class RecentsViewTouchHandler {
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
if (mDragging) {
|
||||
ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger(
|
||||
mRv.getContext());
|
||||
postAnimationTrigger.increment();
|
||||
EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView,
|
||||
mLastDropTarget, postAnimationTrigger));
|
||||
postAnimationTrigger.decrement();
|
||||
mLastDropTarget));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.RecentsActivity;
|
||||
import com.android.systemui.recents.RecentsActivityLaunchState;
|
||||
import com.android.systemui.recents.RecentsConfiguration;
|
||||
import com.android.systemui.recents.RecentsDebugFlags;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
|
||||
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
|
||||
@@ -798,7 +797,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
TaskView frontMostTask = taskViews.get(taskViewCount - 1);
|
||||
event.setFromIndex(mStack.indexOfStackTask(backMostTask.getTask()));
|
||||
event.setToIndex(mStack.indexOfStackTask(frontMostTask.getTask()));
|
||||
event.setContentDescription(frontMostTask.getTask().activityLabel);
|
||||
event.setContentDescription(frontMostTask.getTask().title);
|
||||
}
|
||||
event.setItemCount(mStack.getStackTaskCount());
|
||||
event.setScrollY(mStackScroller.mScroller.getCurrY());
|
||||
@@ -1022,8 +1021,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
if (launchTargetTask != null) {
|
||||
occludesLaunchTarget = launchTargetTask.group.isTaskAboveTask(task,
|
||||
launchTargetTask);
|
||||
hideTask = SystemServicesProxy.isFreeformStack(launchTargetTask.key.stackId) &&
|
||||
SystemServicesProxy.isFreeformStack(task.key.stackId);
|
||||
hideTask = launchTargetTask.isFreeformTask() && task.isFreeformTask();
|
||||
}
|
||||
tv.prepareEnterRecentsAnimation(task.isLaunchTarget, hideTask, occludesLaunchTarget,
|
||||
offscreenY);
|
||||
@@ -1495,7 +1493,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
(!isFreeformTask && event.dropTarget == mFreeformWorkspaceDropTarget) ||
|
||||
(isFreeformTask && event.dropTarget == mStackDropTarget);
|
||||
|
||||
event.postAnimationTrigger.increment();
|
||||
if (hasChangedStacks) {
|
||||
// Move the task to the right position in the stack (ie. the front of the stack if
|
||||
// freeform or the front of the stack if fullscreen). Note, we MUST move the tasks
|
||||
@@ -1508,7 +1505,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
updateLayout(true);
|
||||
|
||||
// Move the task to the new stack in the system after the animation completes
|
||||
event.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
|
||||
event.addPostAnimationCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
@@ -1516,8 +1513,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
});
|
||||
}
|
||||
event.taskView.animate()
|
||||
.withEndAction(event.postAnimationTrigger.decrementAsRunnable());
|
||||
event.getAnimationTrigger().increment();
|
||||
event.taskView.animate().withEndAction(event.getAnimationTrigger().decrementAsRunnable());
|
||||
|
||||
// We translated the view but we need to animate it back from the current layout-space rect
|
||||
// to its final layout-space rect
|
||||
@@ -1557,7 +1554,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
for (int i = 0; i < taskViewCount; i++) {
|
||||
TaskView tv = taskViews.get(i);
|
||||
Task task = tv.getTask();
|
||||
if (SystemServicesProxy.isFreeformStack(task.key.stackId)) {
|
||||
if (task.isFreeformTask()) {
|
||||
tv.setVisibility(event.visible ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
@@ -1578,9 +1575,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
.setUpdateListener(null)
|
||||
.setListener(null)
|
||||
.withLayer()
|
||||
.withEndAction(event.postHideStackAnimationTrigger.decrementAsRunnable())
|
||||
.withEndAction(event.getAnimationTrigger().decrementAsRunnable())
|
||||
.start();
|
||||
event.postHideStackAnimationTrigger.increment();
|
||||
event.getAnimationTrigger().increment();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1593,7 +1590,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
int taskViewCount = taskViews.size();
|
||||
for (int i = taskViewCount - 1; i >= 0; i--) {
|
||||
final TaskView tv = taskViews.get(i);
|
||||
event.postHideHistoryAnimationTrigger.addLastDecrementRunnable(new Runnable() {
|
||||
event.addPostAnimationCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
tv.animate()
|
||||
@@ -1617,7 +1614,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
|
||||
// Announce for accessibility
|
||||
tv.announceForAccessibility(getContext().getString(
|
||||
R.string.accessibility_recents_item_dismissed, tv.getTask().activityLabel));
|
||||
R.string.accessibility_recents_item_dismissed, tv.getTask().title));
|
||||
|
||||
// Remove the task from the stack
|
||||
mStack.removeTask(task);
|
||||
|
||||
@@ -651,7 +651,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
|
||||
*/
|
||||
public void setFocusedState(boolean isFocused, boolean animated, boolean requestViewFocus) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setFocusedState: " + mTask.activityLabel + " focused: " + isFocused +
|
||||
Log.d(TAG, "setFocusedState: " + mTask.title + " focused: " + isFocused +
|
||||
" animated: " + animated + " requestViewFocus: " + requestViewFocus +
|
||||
" isFocused(): " + isFocused() +
|
||||
" isAccessibilityFocused(): " + isAccessibilityFocused());
|
||||
@@ -771,7 +771,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
|
||||
|
||||
public final void onBusEvent(DragEndEvent event) {
|
||||
if (!(event.dropTarget instanceof TaskStack.DockState)) {
|
||||
event.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
|
||||
event.addPostAnimationCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Animate the drag view back from where it is, to the view location, then after
|
||||
|
||||
@@ -60,8 +60,8 @@ public class TaskViewHeader extends FrameLayout
|
||||
// Header views
|
||||
ImageView mMoveTaskButton;
|
||||
ImageView mDismissButton;
|
||||
ImageView mApplicationIcon;
|
||||
TextView mActivityDescription;
|
||||
ImageView mIconView;
|
||||
TextView mTitleView;
|
||||
int mMoveTaskTargetStackId = INVALID_STACK_ID;
|
||||
|
||||
// Header drawables
|
||||
@@ -128,16 +128,16 @@ public class TaskViewHeader extends FrameLayout
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
// Initialize the icon and description views
|
||||
mApplicationIcon = (ImageView) findViewById(R.id.application_icon);
|
||||
mApplicationIcon.setOnLongClickListener(this);
|
||||
mActivityDescription = (TextView) findViewById(R.id.activity_description);
|
||||
mIconView = (ImageView) findViewById(R.id.icon);
|
||||
mIconView.setOnLongClickListener(this);
|
||||
mTitleView = (TextView) findViewById(R.id.title);
|
||||
mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
|
||||
mDismissButton.setOnClickListener(this);
|
||||
mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
|
||||
|
||||
// Hide the backgrounds if they are ripple drawables
|
||||
if (mApplicationIcon.getBackground() instanceof RippleDrawable) {
|
||||
mApplicationIcon.setBackground(null);
|
||||
if (mIconView.getBackground() instanceof RippleDrawable) {
|
||||
mIconView.setBackground(null);
|
||||
}
|
||||
|
||||
mBackgroundColorDrawable = (GradientDrawable) getContext().getDrawable(
|
||||
@@ -158,8 +158,8 @@ public class TaskViewHeader extends FrameLayout
|
||||
public void onTaskViewSizeChanged(int width, int height) {
|
||||
mTaskViewRect.set(0, 0, width, height);
|
||||
boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE;
|
||||
int appIconWidth = mApplicationIcon.getMeasuredWidth();
|
||||
int activityDescWidth = mActivityDescription.getMeasuredWidth();
|
||||
int appIconWidth = mIconView.getMeasuredWidth();
|
||||
int activityDescWidth = mTitleView.getMeasuredWidth();
|
||||
int dismissIconWidth = mDismissButton.getMeasuredWidth();
|
||||
int moveTaskIconWidth = mMoveTaskButton.getVisibility() == View.VISIBLE
|
||||
? mMoveTaskButton.getMeasuredWidth()
|
||||
@@ -168,26 +168,26 @@ public class TaskViewHeader extends FrameLayout
|
||||
// Priority-wise, we show the activity icon first, the dismiss icon if there is room, the
|
||||
// move-task icon if there is room, and then finally, the activity label if there is room
|
||||
if (width < (appIconWidth + dismissIconWidth)) {
|
||||
mActivityDescription.setVisibility(View.INVISIBLE);
|
||||
mTitleView.setVisibility(View.INVISIBLE);
|
||||
if (updateMoveTaskButton) {
|
||||
mMoveTaskButton.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
mDismissButton.setVisibility(View.INVISIBLE);
|
||||
} else if (width < (appIconWidth + dismissIconWidth + moveTaskIconWidth)) {
|
||||
mActivityDescription.setVisibility(View.INVISIBLE);
|
||||
mTitleView.setVisibility(View.INVISIBLE);
|
||||
if (updateMoveTaskButton) {
|
||||
mMoveTaskButton.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
mDismissButton.setVisibility(View.VISIBLE);
|
||||
} else if (width < (appIconWidth + dismissIconWidth + moveTaskIconWidth +
|
||||
activityDescWidth)) {
|
||||
mActivityDescription.setVisibility(View.INVISIBLE);
|
||||
mTitleView.setVisibility(View.INVISIBLE);
|
||||
if (updateMoveTaskButton) {
|
||||
mMoveTaskButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mDismissButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mActivityDescription.setVisibility(View.VISIBLE);
|
||||
mTitleView.setVisibility(View.VISIBLE);
|
||||
if (updateMoveTaskButton) {
|
||||
mMoveTaskButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
@@ -233,15 +233,13 @@ public class TaskViewHeader extends FrameLayout
|
||||
|
||||
// If an activity icon is defined, then we use that as the primary icon to show in the bar,
|
||||
// otherwise, we fall back to the application icon
|
||||
if (t.activityIcon != null) {
|
||||
mApplicationIcon.setImageDrawable(t.activityIcon);
|
||||
} else if (t.applicationIcon != null) {
|
||||
mApplicationIcon.setImageDrawable(t.applicationIcon);
|
||||
if (t.icon != null) {
|
||||
mIconView.setImageDrawable(t.icon);
|
||||
}
|
||||
if (!mActivityDescription.getText().toString().equals(t.activityLabel)) {
|
||||
mActivityDescription.setText(t.activityLabel);
|
||||
if (!mTitleView.getText().toString().equals(t.title)) {
|
||||
mTitleView.setText(t.title);
|
||||
}
|
||||
mActivityDescription.setContentDescription(t.contentDescription);
|
||||
mTitleView.setContentDescription(t.contentDescription);
|
||||
|
||||
// Try and apply the system ui tint
|
||||
int existingBgColor = (getBackground() instanceof ColorDrawable) ?
|
||||
@@ -254,7 +252,7 @@ public class TaskViewHeader extends FrameLayout
|
||||
R.color.recents_task_bar_light_text_color);
|
||||
int taskBarViewDarkTextColor = getResources().getColor(
|
||||
R.color.recents_task_bar_dark_text_color);
|
||||
mActivityDescription.setTextColor(t.useLightOnPrimaryColor ?
|
||||
mTitleView.setTextColor(t.useLightOnPrimaryColor ?
|
||||
taskBarViewLightTextColor : taskBarViewDarkTextColor);
|
||||
mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
|
||||
mLightDismissDrawable : mDarkDismissDrawable);
|
||||
@@ -281,15 +279,15 @@ public class TaskViewHeader extends FrameLayout
|
||||
|
||||
// In accessibility, a single click on the focused app info button will show it
|
||||
if (ssp.isTouchExplorationEnabled()) {
|
||||
mApplicationIcon.setOnClickListener(this);
|
||||
mIconView.setOnClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Unbinds the bar view from the task */
|
||||
void unbindFromTask() {
|
||||
mTask = null;
|
||||
mApplicationIcon.setImageDrawable(null);
|
||||
mApplicationIcon.setOnClickListener(null);
|
||||
mIconView.setImageDrawable(null);
|
||||
mIconView.setOnClickListener(null);
|
||||
mMoveTaskButton.setOnClickListener(null);
|
||||
}
|
||||
|
||||
@@ -357,7 +355,7 @@ public class TaskViewHeader extends FrameLayout
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v == mApplicationIcon) {
|
||||
if (v == mIconView) {
|
||||
// In accessibility, a single click on the focused app info button will show it
|
||||
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
|
||||
} else if (v == mDismissButton) {
|
||||
@@ -379,7 +377,7 @@ public class TaskViewHeader extends FrameLayout
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (v == mApplicationIcon) {
|
||||
if (v == mIconView) {
|
||||
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user