diff options
author | Winson Chung <winsonc@google.com> | 2014-03-21 16:07:22 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-03-21 16:07:22 -0700 |
commit | fb504779320f7343dfc5a0abe12954f922dd90b0 (patch) | |
tree | dc556e82fbe1a45821334c5b1a8e949af995d38a | |
parent | 945f836acc6920bd95c2995075ba3e1255a66d80 (diff) | |
parent | e9c77aee60fbb781db916d32fe1db81e1d973f8f (diff) | |
download | frameworks_base-fb504779320f7343dfc5a0abe12954f922dd90b0.zip frameworks_base-fb504779320f7343dfc5a0abe12954f922dd90b0.tar.gz frameworks_base-fb504779320f7343dfc5a0abe12954f922dd90b0.tar.bz2 |
am e9c77aee: Merge "Fixing crash with multiple touch pointers"
* commit 'e9c77aee60fbb781db916d32fe1db81e1d973f8f':
Fixing crash with multiple touch pointers
5 files changed, 94 insertions, 37 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java index c5e325e..cdbee82 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java @@ -29,45 +29,73 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.UserHandle; import android.util.LruCache; +import android.util.Pair; import com.android.systemui.recents.model.SpaceNode; import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; 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>(); - Task nextTask() { - Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|nextTask]"); - return mQueue.poll(); - } + static final Boolean sFalse = new Boolean(false); - void addTask(Task t) { + /** Adds a new task to the load queue */ + void addTask(Task t, boolean forceLoad) { Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|addTask]"); if (!mQueue.contains(t)) { mQueue.add(t); } + if (forceLoad) { + mForceLoadSet.put(t.key, new Boolean(true)); + } synchronized(this) { notifyAll(); } } + /** + * Retrieves the next task from the load queue, as well as whether we want that task to be + * force reloaded. + */ + Pair<Task, Boolean> nextTask() { + Console.log(Constants.DebugFlags.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); + } + + /** Removes a task from the load queue */ void removeTask(Task t) { Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|removeTask]"); mQueue.remove(t); + mForceLoadSet.remove(t.key); } + /** Clears all the tasks from the load queue */ void clearTasks() { Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|clearTasks]"); mQueue.clear(); + mForceLoadSet.clear(); } + /** Returns whether the load queue is empty */ boolean isEmpty() { return mQueue.isEmpty(); } @@ -147,16 +175,19 @@ class TaskResourceLoader implements Runnable { } } else { // Load the next item from the queue - final Task t = mLoadQueue.nextTask(); + Pair<Task, Boolean> nextTaskData = mLoadQueue.nextTask(); + final Task t = nextTaskData.first; + final boolean forceLoadTask = nextTaskData.second; if (t != null) { try { Drawable loadIcon = mIconCache.get(t.key); Bitmap loadThumbnail = mThumbnailCache.get(t.key); Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoader|load]", - t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail); + t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail + + " forceLoad: " + forceLoadTask); // Load the icon - if (loadIcon == null) { + if (loadIcon == null || forceLoadTask) { PackageManager pm = mContext.getPackageManager(); ActivityInfo info = pm.getActivityInfo(t.key.intent.getComponent(), PackageManager.GET_META_DATA); @@ -172,7 +203,7 @@ class TaskResourceLoader implements Runnable { } } // Load the thumbnail - if (loadThumbnail == null) { + if (loadThumbnail == null || forceLoadTask) { ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); Bitmap thumbnail = am.getTaskTopThumbnail(t.key.id); @@ -197,7 +228,7 @@ class TaskResourceLoader implements Runnable { mMainThreadHandler.post(new Runnable() { @Override public void run() { - t.notifyTaskDataLoaded(newThumbnail, newIcon); + t.notifyTaskDataLoaded(newThumbnail, newIcon, forceLoadTask); } }); } @@ -329,9 +360,11 @@ public class RecentsTaskLoader { /** Reload the set of recent tasks */ SpaceNode reload(Context context, int preloadCount) { Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]"); + ArrayList<Task> tasksToForceLoad = new ArrayList<Task>(); TaskStack stack = new TaskStack(context); SpaceNode root = new SpaceNode(context); root.setStack(stack); + try { long t1 = System.currentTimeMillis(); @@ -387,6 +420,12 @@ public class RecentsTaskLoader { // Load the icon (if possible and not the foremost task, from the cache) 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 (task.icon == null) { task.icon = info.loadIcon(pm); @@ -400,6 +439,12 @@ public class RecentsTaskLoader { // Load the thumbnail (if possible and not the foremost task, from the cache) if (!isForemostTask) { task.thumbnail = mThumbnailCache.get(task.key); + + if (task.thumbnail != 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.thumbnail == null) { Console.log(Constants.DebugFlags.App.TaskDataLoader, @@ -451,6 +496,11 @@ public class RecentsTaskLoader { // 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); + } + return root; } @@ -473,9 +523,9 @@ public class RecentsTaskLoader { requiresLoad = true; } if (requiresLoad) { - mLoadQueue.addTask(t); + mLoadQueue.addTask(t, false); } - t.notifyTaskDataLoaded(thumbnail, icon); + t.notifyTaskDataLoaded(thumbnail, icon, false); } /** Releases the task resource data back into the pool. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java index 0c3c528..edcf9b2 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -29,7 +29,7 @@ public class Task { /* Task callbacks */ public interface TaskCallbacks { /* Notifies when a task has been bound */ - public void onTaskDataLoaded(); + public void onTaskDataLoaded(boolean reloadingTaskData); /* Notifies when a task has been unbound */ public void onTaskDataUnloaded(); } @@ -84,11 +84,11 @@ public class Task { } /** Notifies the callback listeners that this task has been loaded */ - public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon) { + public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon, boolean reloadingTaskData) { this.icon = icon; this.thumbnail = thumbnail; if (mCb != null) { - mCb.onTaskDataLoaded(); + mCb.onTaskDataLoaded(reloadingTaskData); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 62cf394..2b27a06 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -881,6 +881,13 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { } break; } + case MotionEvent.ACTION_POINTER_DOWN: { + final int index = ev.getActionIndex(); + mActivePointerId = ev.getPointerId(index); + mLastMotionX = (int) ev.getX(index); + mLastMotionY = (int) ev.getY(index); + break; + } case MotionEvent.ACTION_MOVE: { if (mActivePointerId == INACTIVE_POINTER_ID) break; @@ -957,6 +964,19 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { recycleVelocityTracker(); break; } + case MotionEvent.ACTION_POINTER_UP: { + int pointerIndex = ev.getActionIndex(); + int pointerId = ev.getPointerId(pointerIndex); + if (pointerId == mActivePointerId) { + // Select a new active pointer id and reset the motion state + final int newPointerIndex = (pointerIndex == 0) ? 1 : 0; + mActivePointerId = ev.getPointerId(newPointerIndex); + mLastMotionX = (int) ev.getX(newPointerIndex); + mLastMotionY = (int) ev.getY(newPointerIndex); + mVelocityTracker.clear(); + } + break; + } case MotionEvent.ACTION_CANCEL: { if (mIsScrolling) { // Disable HW layers @@ -1006,10 +1026,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { Task task = tv.getTask(); Activity activity = (Activity) mSv.getContext(); - // We have to disable the listener to ensure that we - // don't hit this again - tv.animate().setListener(null); - // Remove the task from the view mSv.mStack.removeTask(task); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index f411717..e6dce37 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -65,10 +65,7 @@ class TaskThumbnailView extends ImageView { setImageBitmap(t.thumbnail); if (animate) { - setAlpha(0f); - animate().alpha(1f) - .setDuration(Constants.Values.TaskView.Animation.TaskDataUpdatedFadeDuration) - .start(); + // XXX: Investigate how expensive it will be to create a second bitmap and crossfade } } } @@ -143,10 +140,7 @@ class TaskIconView extends ImageView { if (t.icon != null) { setImageDrawable(t.icon); if (animate) { - setAlpha(0f); - animate().alpha(1f) - .setDuration(Constants.Values.TaskView.Animation.TaskDataUpdatedFadeDuration) - .start(); + // XXX: Investigate how expensive it will be to create a second bitmap and crossfade } } } @@ -311,6 +305,7 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. .translationY(0) .setStartDelay(235) .setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration) + .withLayer() .start(); } } @@ -333,13 +328,8 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. .setStartDelay(0) .setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration) .setInterpolator(new DecelerateInterpolator()) - .setListener( - new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - r.run(); - } - }) + .withLayer() + .withEndAction(r) .start(); } } @@ -379,10 +369,10 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. } @Override - public void onTaskDataLoaded() { + public void onTaskDataLoaded(boolean reloadingTaskData) { // Bind each of the views to the new task data - mThumbnailView.rebindToTask(mTask, false); - mIconView.rebindToTask(mTask, false); + mThumbnailView.rebindToTask(mTask, reloadingTaskData); + mIconView.rebindToTask(mTask, reloadingTaskData); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 034edf9..68c8364 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -757,6 +757,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected void toggleRecentsActivity() { if (mRecents != null) { + sendCloseSystemWindows(mContext, SYSTEM_DIALOG_REASON_RECENT_APPS); mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView()); } } |