Merge "Change layout size to be dependent on device size" into ub-launcher3-master
diff --git a/go/quickstep/res/layout/icon_recents_root_view.xml b/go/quickstep/res/layout/icon_recents_root_view.xml
index fddb1d3..6300882 100644
--- a/go/quickstep/res/layout/icon_recents_root_view.xml
+++ b/go/quickstep/res/layout/icon_recents_root_view.xml
@@ -33,10 +33,9 @@
             android:scrollbars="none"/>
         <Button
             android:id="@+id/clear_all_button"
-            android:layout_width="@dimen/clear_all_button_width"
-            android:layout_height="@dimen/clear_all_button_height"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
-            android:layout_marginVertical="@dimen/task_item_half_vert_margin"
             android:background="@drawable/clear_all_button"
             android:gravity="center"
             android:text="@string/recents_clear_all"
diff --git a/go/quickstep/res/layout/task_item_view.xml b/go/quickstep/res/layout/task_item_view.xml
index 048e9c5..2198237 100644
--- a/go/quickstep/res/layout/task_item_view.xml
+++ b/go/quickstep/res/layout/task_item_view.xml
@@ -21,20 +21,19 @@
     android:orientation="horizontal">
     <FrameLayout
         android:id="@+id/task_icon_and_thumbnail"
-        android:layout_width="@dimen/task_thumbnail_and_icon_view_size"
-        android:layout_height="@dimen/task_thumbnail_and_icon_view_size"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
         android:layout_gravity="center_vertical"
-        android:layout_marginHorizontal="8dp"
-        android:layout_marginVertical="@dimen/task_item_half_vert_margin">
+        android:layout_marginHorizontal="8dp">
         <ImageView
             android:id="@+id/task_thumbnail"
-            android:layout_width="@dimen/task_thumbnail_width"
-            android:layout_height="@dimen/task_thumbnail_height"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
             android:layout_gravity="top|start"/>
         <ImageView
             android:id="@+id/task_icon"
-            android:layout_width="@dimen/task_icon_size"
-            android:layout_height="@dimen/task_icon_size"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_gravity="bottom|end"/>
     </FrameLayout>
     <TextView
diff --git a/go/quickstep/res/values/dimens.xml b/go/quickstep/res/values/dimens.xml
deleted file mode 100644
index e2fa387..0000000
--- a/go/quickstep/res/values/dimens.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2019 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.
--->
-<resources>
-    <dimen name="task_item_half_vert_margin">8dp</dimen>
-    <dimen name="task_thumbnail_and_icon_view_size">60dp</dimen>
-    <dimen name="task_thumbnail_height">60dp</dimen>
-    <dimen name="task_thumbnail_width">36dp</dimen>
-    <dimen name="task_icon_size">36dp</dimen>
-
-    <dimen name="clear_all_button_width">106dp</dimen>
-    <dimen name="clear_all_button_height">36dp</dimen>
-</resources>
\ No newline at end of file
diff --git a/go/quickstep/src/com/android/quickstep/TaskAdapter.java b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
index 5e0e8ff..f1fc9de 100644
--- a/go/quickstep/src/com/android/quickstep/TaskAdapter.java
+++ b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
@@ -15,12 +15,18 @@
  */
 package com.android.quickstep;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+import static com.android.quickstep.views.TaskLayoutUtils.getTaskHeight;
+import static com.android.quickstep.views.TaskLayoutUtils.getTaskTopMargin;
+
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
 import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.RecyclerView.Adapter;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.quickstep.views.TaskItemView;
 import com.android.systemui.shared.recents.model.Task;
@@ -35,15 +41,17 @@
 public final class TaskAdapter extends Adapter<TaskHolder> {
 
     public static final int CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT = 0;
+    public static final int MAX_TASKS_TO_DISPLAY = 6;
 
-    private static final int MAX_TASKS_TO_DISPLAY = 6;
     private static final String TAG = "TaskAdapter";
     private final TaskListLoader mLoader;
+    private final DeviceProfile mDeviceProfile;
     private TaskActionController mTaskActionController;
     private boolean mIsShowingLoadingUi;
 
-    public TaskAdapter(@NonNull TaskListLoader loader) {
+    public TaskAdapter(@NonNull TaskListLoader loader, DeviceProfile dp) {
         mLoader = loader;
+        mDeviceProfile = dp;
     }
 
     public void setActionController(TaskActionController taskActionController) {
@@ -66,6 +74,11 @@
     public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         TaskItemView itemView = (TaskItemView) LayoutInflater.from(parent.getContext())
                 .inflate(R.layout.task_item_view, parent, false);
+        ViewGroup.MarginLayoutParams itemViewParams =
+                (ViewGroup.MarginLayoutParams) itemView.getLayoutParams();
+        itemViewParams.width = MATCH_PARENT;
+        itemViewParams.height = getTaskHeight(mDeviceProfile);
+        itemViewParams.topMargin = getTaskTopMargin(mDeviceProfile);
         TaskHolder holder = new TaskHolder(itemView);
         itemView.setOnClickListener(view -> mTaskActionController.launchTask(holder));
         return holder;
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index 4724406..2c4abc5 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -18,6 +18,10 @@
 import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
 
 import static com.android.quickstep.TaskAdapter.CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT;
+import static com.android.quickstep.views.TaskLayoutUtils.getClearAllButtonHeight;
+import static com.android.quickstep.views.TaskLayoutUtils.getClearAllButtonTopBottomMargin;
+import static com.android.quickstep.views.TaskLayoutUtils.getClearAllButtonWidth;
+import static com.android.quickstep.views.TaskLayoutUtils.getTaskListHeight;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -31,6 +35,7 @@
 import android.util.FloatProperty;
 import android.view.View;
 import android.view.ViewDebug;
+import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
 
@@ -43,6 +48,8 @@
 import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
 import androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener;
 
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.quickstep.ContentFillItemAnimator;
 import com.android.quickstep.RecentsToActivityHelper;
@@ -96,6 +103,7 @@
     private final DefaultItemAnimator mDefaultItemAnimator = new DefaultItemAnimator();
     private final ContentFillItemAnimator mLoadingContentItemAnimator =
             new ContentFillItemAnimator();
+    private final DeviceProfile mDeviceProfile;
 
     private RecentsToActivityHelper mActivityHelper;
     private RecyclerView mTaskRecyclerView;
@@ -109,9 +117,11 @@
 
     public IconRecentsView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        BaseActivity activity = BaseActivity.fromContext(context);
         mContext = context;
+        mDeviceProfile = activity.getDeviceProfile();
         mTaskLoader = new TaskListLoader(mContext);
-        mTaskAdapter = new TaskAdapter(mTaskLoader);
+        mTaskAdapter = new TaskAdapter(mTaskLoader, mDeviceProfile);
         mTaskActionController = new TaskActionController(mTaskLoader, mTaskAdapter);
         mTaskAdapter.setActionController(mTaskActionController);
     }
@@ -121,6 +131,8 @@
         super.onFinishInflate();
         if (mTaskRecyclerView == null) {
             mTaskRecyclerView = findViewById(R.id.recent_task_recycler_view);
+            ViewGroup.LayoutParams recyclerViewParams = mTaskRecyclerView.getLayoutParams();
+            recyclerViewParams.height = getTaskListHeight(mDeviceProfile);
             mTaskRecyclerView.setAdapter(mTaskAdapter);
             mTaskRecyclerView.setLayoutManager(
                     new LinearLayoutManager(mContext, VERTICAL, true /* reverseLayout */));
@@ -159,6 +171,12 @@
                 }
             });
             mClearAllView = findViewById(R.id.clear_all_button);
+            MarginLayoutParams clearAllParams =
+                    (MarginLayoutParams) mClearAllView.getLayoutParams();
+            clearAllParams.height = getClearAllButtonHeight(mDeviceProfile);
+            clearAllParams.width = getClearAllButtonWidth(mDeviceProfile);
+            clearAllParams.topMargin = getClearAllButtonTopBottomMargin(mDeviceProfile);
+            clearAllParams.bottomMargin = getClearAllButtonTopBottomMargin(mDeviceProfile);
             mClearAllView.setOnClickListener(v -> animateClearAllTasks());
         }
     }
diff --git a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
index 572747b..4392c68 100644
--- a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
+++ b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
@@ -15,6 +15,8 @@
  */
 package com.android.quickstep.views;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -23,6 +25,8 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -39,6 +43,7 @@
 
     private static final String EMPTY_LABEL = "";
     private static final String DEFAULT_LABEL = "...";
+    private static final float SUBITEM_FRAME_RATIO = .6f;
     private final Drawable mDefaultIcon;
     private final Drawable mDefaultThumbnail;
     private final TaskLayerDrawable mIconDrawable;
@@ -46,6 +51,7 @@
     private TextView mLabelView;
     private ImageView mIconView;
     private ImageView mThumbnailView;
+    private FrameLayout mThumbnailIconFrame;
     private float mContentTransitionProgress;
 
     /**
@@ -80,6 +86,7 @@
         mLabelView = findViewById(R.id.task_label);
         mThumbnailView = findViewById(R.id.task_thumbnail);
         mIconView = findViewById(R.id.task_icon);
+        mThumbnailIconFrame = findViewById(R.id.task_icon_and_thumbnail);
 
         mThumbnailView.setImageDrawable(mThumbnailDrawable);
         mIconView.setImageDrawable(mIconDrawable);
@@ -88,6 +95,31 @@
         CONTENT_TRANSITION_PROGRESS.setValue(this, 1.0f);
     }
 
+    @Override
+    public void setLayoutParams(ViewGroup.LayoutParams params) {
+        super.setLayoutParams(params);
+
+        // TODO: Rather than setting child layout params, make custom views and override onMeasure.
+        if (mThumbnailIconFrame == null
+                || mIconView == null
+                || mThumbnailView == null) {
+            // Views not initialized yet.
+            return;
+        }
+
+        int frameSize = params.height;
+        ViewGroup.LayoutParams frameParams = mThumbnailIconFrame.getLayoutParams();
+        frameParams.width = frameSize;
+
+        int frameSubItemWidth = (int) (SUBITEM_FRAME_RATIO * frameSize);
+        ViewGroup.LayoutParams thumbnailParams = mThumbnailView.getLayoutParams();
+        thumbnailParams.width = frameSubItemWidth;
+
+        ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams();
+        iconParams.width = frameSubItemWidth;
+        iconParams.height = frameSubItemWidth;
+    }
+
     /**
      * Resets task item view to empty, loading UI.
      */
diff --git a/go/quickstep/src/com/android/quickstep/views/TaskLayoutUtils.java b/go/quickstep/src/com/android/quickstep/views/TaskLayoutUtils.java
new file mode 100644
index 0000000..1b50707
--- /dev/null
+++ b/go/quickstep/src/com/android/quickstep/views/TaskLayoutUtils.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 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.views;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.quickstep.TaskAdapter;
+
+/**
+ * Utils to determine dynamically task and view sizes based off the device height and width.
+ */
+public final class TaskLayoutUtils {
+
+    private static final float BUTTON_TO_DEVICE_HEIGHT_RATIO = 36.0f/569;
+    private static final float BUTTON_WIDTH_TO_HEIGHT_RATIO = 53.0f/18;
+    private static final float BUTTON_MARGIN_TO_BUTTON_HEIGHT_RATIO = 5.0f/9;
+    private static final float TASK_TO_DEVICE_HEIGHT_RATIO = 15.0f/19;
+    private static final float TASK_MARGIN_TO_TASK_HEIGHT_RATIO = 4.0f/15;
+
+    private TaskLayoutUtils() {}
+
+    public static int getTaskHeight(DeviceProfile dp) {
+        return (int) (TASK_TO_DEVICE_HEIGHT_RATIO * getTaskItemSpace(dp));
+    }
+
+    public static int getTaskTopMargin(DeviceProfile dp) {
+        return (int) (TASK_MARGIN_TO_TASK_HEIGHT_RATIO * getTaskHeight(dp));
+    }
+
+    private static int getTaskItemSpace(DeviceProfile dp) {
+        return getTaskListHeight(dp) / TaskAdapter.MAX_TASKS_TO_DISPLAY;
+    }
+
+    public static int getTaskListHeight(DeviceProfile dp) {
+        int clearAllSpace = getClearAllButtonHeight(dp) + 2 * getClearAllButtonTopBottomMargin(dp);
+        return getDeviceLongWidth(dp) - clearAllSpace;
+    }
+
+    public static int getClearAllButtonHeight(DeviceProfile dp) {
+        return (int) (BUTTON_TO_DEVICE_HEIGHT_RATIO * getDeviceLongWidth(dp));
+    }
+
+    public static int getClearAllButtonWidth(DeviceProfile dp) {
+        return (int) (BUTTON_WIDTH_TO_HEIGHT_RATIO * getClearAllButtonHeight(dp));
+    }
+
+    public static int getClearAllButtonTopBottomMargin(DeviceProfile dp) {
+        return (int) (BUTTON_MARGIN_TO_BUTTON_HEIGHT_RATIO * getClearAllButtonHeight(dp));
+    }
+
+    private static int getDeviceLongWidth(DeviceProfile dp) {
+        return Math.max(dp.availableHeightPx, dp.availableWidthPx);
+    }
+}