Adding some task views.

Bug: 69166452
Test: Build quickstep
Change-Id: Iee4cb0b9ac32716f588082a197a90ec1b2655047
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index f9ce6e0..a76f4f9 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/res/drawable/task_thumbnail_background.xml b/quickstep/res/drawable/task_thumbnail_background.xml
new file mode 100644
index 0000000..27efd6c
--- /dev/null
+++ b/quickstep/res/drawable/task_thumbnail_background.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <solid android:color="#FF000000" />
+    <corners android:radius="6dp" />
+</shape>
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
new file mode 100644
index 0000000..9d8aea7
--- /dev/null
+++ b/quickstep/res/layout/task.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.quickstep.TaskView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.android.quickstep.TaskThumbnailView
+        android:id="@+id/snapshot"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:scaleType="matrix"
+        android:background="@drawable/task_thumbnail_background"
+        android:elevation="4dp" />
+    <ImageView
+        android:id="@+id/icon"
+        android:layout_width="36dp"
+        android:layout_height="36dp"
+        android:layout_gravity="top|center_horizontal"
+        android:elevation="5dp"/>
+</com.android.quickstep.TaskView>
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 8f75980..a0340b6 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -40,7 +40,7 @@
         plan.preloadPlan(new RecentsTaskLoader(this, 1, 1, 0), -1, UserHandle.myUserId());
 
         mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
-        mAdapter.addAll(plan.getTaskStack().getStackTasks());
+        mAdapter.addAll(plan.getTaskStack().getTasks());
         setListAdapter(mAdapter);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/TaskThumbnailView.java
new file mode 100644
index 0000000..96c93c2
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailView.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.LightingColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+import android.view.Display;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.widget.FrameLayout;
+
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+/**
+ * A task in the Recents view.
+ */
+public class TaskThumbnailView extends FrameLayout {
+
+    private ThumbnailData mThumbnailData;
+
+    private Rect mThumbnailRect = new Rect();
+    private float mThumbnailScale;
+
+    private Matrix mMatrix = new Matrix();
+    private Paint mDrawPaint = new Paint();
+    protected Paint mBgFillPaint = new Paint();
+    protected BitmapShader mBitmapShader;
+
+    private float mDimAlpha;
+    private LightingColorFilter mLightingColorFilter = new LightingColorFilter(Color.WHITE, 0);
+
+    public TaskThumbnailView(Context context) {
+        this(context, null);
+    }
+
+    public TaskThumbnailView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        setWillNotDraw(false);
+        setDimAlpha(1f);
+        setClipToOutline(true);
+    }
+
+    /**
+     * Updates this thumbnail.
+     */
+    public void setThumbnail(ThumbnailData thumbnailData) {
+        if (thumbnailData != null && thumbnailData.thumbnail != null) {
+            Bitmap bm = thumbnailData.thumbnail;
+            bm.prepareToDraw();
+            mThumbnailScale = thumbnailData.scale;
+            mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+            mDrawPaint.setShader(mBitmapShader);
+            mThumbnailRect.set(0, 0,
+                    bm.getWidth() - thumbnailData.insets.left - thumbnailData.insets.right,
+                    bm.getHeight() - thumbnailData.insets.top - thumbnailData.insets.bottom);
+            mThumbnailData = thumbnailData;
+            updateThumbnailMatrix();
+            updateThumbnailPaintFilter();
+        } else {
+            mBitmapShader = null;
+            mDrawPaint.setShader(null);
+            mThumbnailRect.setEmpty();
+            mThumbnailData = null;
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        int viewWidth = getMeasuredWidth();
+        int viewHeight = getMeasuredHeight();
+        int thumbnailWidth = Math.min(viewWidth,
+                (int) (mThumbnailRect.width() * mThumbnailScale));
+        int thumbnailHeight = Math.min(viewHeight,
+                (int) (mThumbnailRect.height() * mThumbnailScale));
+
+        if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
+            int topOffset = 0;
+            // Draw the background, there will be some small overdraw with the thumbnail
+            if (thumbnailWidth < viewWidth) {
+                // Portrait thumbnail on a landscape task view
+                canvas.drawRect(Math.max(0, thumbnailWidth), topOffset, viewWidth, viewHeight,
+                        mBgFillPaint);
+            }
+            if (thumbnailHeight < viewHeight) {
+                // Landscape thumbnail on a portrait task view
+                canvas.drawRect(0, Math.max(topOffset, thumbnailHeight), viewWidth, viewHeight,
+                        mBgFillPaint);
+            }
+
+            // Draw the thumbnail
+            canvas.drawRect(0, topOffset, thumbnailWidth, thumbnailHeight, mDrawPaint);
+        } else {
+            canvas.drawRect(0, 0, viewWidth, viewHeight, mBgFillPaint);
+        }
+    }
+
+    void updateThumbnailPaintFilter() {
+        int mul = (int) ((1.0f - mDimAlpha) * 255);
+        if (mBitmapShader != null) {
+            mLightingColorFilter = new LightingColorFilter(Color.WHITE,
+                    Color.argb(255, mul, mul, mul));
+            mDrawPaint.setColorFilter(mLightingColorFilter);
+            mDrawPaint.setColor(0xFFffffff);
+            mBgFillPaint.setColorFilter(mLightingColorFilter);
+        } else {
+            int grey = mul;
+            mDrawPaint.setColorFilter(null);
+            mDrawPaint.setColor(Color.argb(255, grey, grey, grey));
+        }
+        invalidate();
+    }
+
+    public void updateThumbnailMatrix() {
+        mThumbnailScale = 1f;
+        if (mBitmapShader != null && mThumbnailData != null) {
+            if (getMeasuredWidth() == 0) {
+                // If we haven't measured , skip the thumbnail drawing and only draw the background
+                // color
+                mThumbnailScale = 0f;
+            } else {
+                float invThumbnailScale = 1f / mThumbnailScale;
+                final Configuration configuration =
+                        getContext().getApplicationContext().getResources().getConfiguration();
+                final Point displaySize = new Point();
+                getDisplay().getRealSize(displaySize);
+                if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
+                    if (mThumbnailData.orientation == Configuration.ORIENTATION_PORTRAIT) {
+                        // If we are in the same orientation as the screenshot, just scale it to the
+                        // width of the task view
+                        mThumbnailScale = (float) getMeasuredWidth() / mThumbnailRect.width();
+                    } else {
+                        // Scale the landscape thumbnail up to app size, then scale that to the task
+                        // view size to match other portrait screenshots
+                        mThumbnailScale = invThumbnailScale *
+                                ((float) getMeasuredWidth() / displaySize.x);
+                    }
+                } else {
+                    // Otherwise, scale the screenshot to fit 1:1 in the current orientation
+                    mThumbnailScale = invThumbnailScale;
+                }
+            }
+            mMatrix.setTranslate(-mThumbnailData.insets.left * mThumbnailScale,
+                    -mThumbnailData.insets.top * mThumbnailScale);
+            mMatrix.postScale(mThumbnailScale, mThumbnailScale);
+            mBitmapShader.setLocalMatrix(mMatrix);
+        }
+        invalidate();
+    }
+
+    public void setDimAlpha(float dimAlpha) {
+        mDimAlpha = dimAlpha;
+        updateThumbnailPaintFilter();
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/TaskView.java b/quickstep/src/com/android/quickstep/TaskView.java
new file mode 100644
index 0000000..ea584f0
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskView.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.android.launcher3.R;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskCallbacks;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+
+/**
+ * A task in the Recents view.
+ */
+public class TaskView extends FrameLayout implements TaskCallbacks {
+
+    private Task mTask;
+    private TaskThumbnailView mSnapshotView;
+    private ImageView mIconView;
+
+    public TaskView(Context context) {
+        this(context, null);
+    }
+
+    public TaskView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        setWillNotDraw(false);
+        setOnClickListener((view) -> {
+            if (mTask != null) {
+                ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(mTask.key,
+                        null, null, null);
+            }
+        });
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        mSnapshotView = findViewById(R.id.snapshot);
+        mIconView = findViewById(R.id.icon);
+    }
+
+    /**
+     * Updates this task view to the given {@param task}.
+     */
+    public void bind(Task task) {
+        mTask = task;
+        task.addCallback(this);
+    }
+
+    @Override
+    public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData) {
+        mSnapshotView.setThumbnail(thumbnailData);
+        mSnapshotView.setDimAlpha(1f);
+        mIconView.setImageDrawable(task.icon);
+    }
+
+    @Override
+    public void onTaskDataUnloaded() {
+        // Do nothing
+    }
+
+    @Override
+    public void onTaskWindowingModeChanged() {
+        // Do nothing
+    }
+}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 75968ae..553a136 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -222,15 +222,12 @@
     @Thunk DragLayer mDragLayer;
     private DragController mDragController;
 
-    public View mWeightWatcher;
-
     private AppWidgetManagerCompat mAppWidgetManager;
     private LauncherAppWidgetHost mAppWidgetHost;
 
     private final int[] mTmpAddItemCellCoordinates = new int[2];
 
     @Thunk Hotseat mHotseat;
-    private ViewGroup mOverviewPanel;
 
     private View mAllAppsButton;
 
@@ -240,6 +237,9 @@
     @Thunk AllAppsContainerView mAppsView;
     AllAppsTransitionController mAllAppsController;
 
+    // UI and state for the overview panel
+    private ViewGroup mOverviewPanel;
+
     // We need to store the orientation Launcher was created with, due to a bug (b/64916689)
     // that results in widgets being inflated in the wrong orientation.
     private int mOrientation;
@@ -1303,8 +1303,8 @@
         return mHotseat;
     }
 
-    public ViewGroup getOverviewPanel() {
-        return mOverviewPanel;
+    public <T extends ViewGroup> T getOverviewPanel() {
+        return (T) mOverviewPanel;
     }
 
     public DropTargetBar getDropTargetBar() {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index daa9bd0..1f87c00 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -296,7 +296,6 @@
 
         mLauncher = Launcher.getLauncher(context);
         mStateTransitionAnimation = new WorkspaceStateTransitionAnimation(mLauncher, this);
-        final Resources res = getResources();
         DeviceProfile grid = mLauncher.getDeviceProfile();
         mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens();
         mWallpaperManager = WallpaperManager.getInstance(context);