Merge "Landscape support 1/n" into ub-launcher3-qt-dev
diff --git a/res/layout-land/fragment_clock_picker.xml b/res/layout-land/fragment_clock_picker.xml
new file mode 100644
index 0000000..a292876
--- /dev/null
+++ b/res/layout-land/fragment_clock_picker.xml
@@ -0,0 +1,68 @@
+<?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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="?android:colorPrimary">
+    <include layout="@layout/section_header"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal">
+
+        <com.android.customization.widget.PreviewPager
+            android:id="@+id/clock_preview_pager"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="@color/secondary_color"
+            app:card_style="screen_aspect_ratio"/>
+
+        <LinearLayout
+            android:id="@+id/options_section"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:paddingVertical="10dp"
+            android:orientation="vertical">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/options_container"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"/>
+
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingHorizontal="10dp">
+                <Button
+                    android:id="@+id/apply_button"
+                    style="@style/ActionPrimaryButton"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentEnd="true"
+                    android:text="@string/apply_btn"/>
+            </RelativeLayout>
+
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/res/layout-land/fragment_grid_picker.xml b/res/layout-land/fragment_grid_picker.xml
new file mode 100644
index 0000000..20ee447
--- /dev/null
+++ b/res/layout-land/fragment_grid_picker.xml
@@ -0,0 +1,65 @@
+<?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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:background="?android:colorPrimary">
+    <include layout="@layout/section_header"/>
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal">
+        <com.android.customization.widget.PreviewPager
+            android:id="@+id/grid_preview_pager"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="@color/secondary_color"
+            app:card_style="screen_aspect_ratio"/>
+
+        <LinearLayout
+            android:id="@+id/options_section"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:paddingVertical="10dp"
+            android:orientation="vertical">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/options_container"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"/>
+
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingHorizontal="10dp">
+                <Button
+                    android:id="@+id/apply_button"
+                    style="@style/ActionPrimaryButton"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentEnd="true"
+                    android:text="@string/apply_btn"/>
+            </RelativeLayout>
+
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/res/layout-land/fragment_theme_picker.xml b/res/layout-land/fragment_theme_picker.xml
new file mode 100644
index 0000000..5caf7b3
--- /dev/null
+++ b/res/layout-land/fragment_theme_picker.xml
@@ -0,0 +1,74 @@
+<?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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="?android:colorPrimary">
+    <include layout="@layout/section_header"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal">
+
+        <com.android.customization.widget.PreviewPager
+            android:id="@+id/theme_preview_pager"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="@color/secondary_color"/>
+
+        <LinearLayout
+            android:id="@+id/options_section"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:paddingVertical="10dp"
+            android:orientation="vertical">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/options_container"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"/>
+
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingHorizontal="10dp">
+                <CheckBox
+                    android:id="@+id/use_my_wallpaper"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentStart="true"
+                    android:layout_centerVertical="true"
+                    android:paddingLeft="4dp"
+                    android:minHeight="@dimen/min_taptarget_height"
+                    android:text="@string/keep_my_wallpaper"/>
+                <Button
+                    android:id="@+id/apply_button"
+                    style="@style/ActionPrimaryButton"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentEnd="true"
+                    android:text="@string/apply_theme_btn"/>
+            </RelativeLayout>
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/clock_option.xml b/res/layout/clock_option.xml
index 467263d..30aa14f 100644
--- a/res/layout/clock_option.xml
+++ b/res/layout/clock_option.xml
@@ -16,7 +16,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
-    android:layout_height="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingRight="2dp"
+    android:paddingBottom="@dimen/option_bottom_margin"
     android:orientation="vertical">
 
     <TextView
diff --git a/res/layout/grid_option.xml b/res/layout/grid_option.xml
index 0dac4fe..5edcdc9 100644
--- a/res/layout/grid_option.xml
+++ b/res/layout/grid_option.xml
@@ -16,7 +16,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
-    android:layout_height="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingRight="2dp"
+    android:paddingBottom="@dimen/option_bottom_margin"
     android:orientation="vertical">
 
     <TextView
diff --git a/res/layout/theme_option.xml b/res/layout/theme_option.xml
index f0c7777..de81231 100644
--- a/res/layout/theme_option.xml
+++ b/res/layout/theme_option.xml
@@ -16,7 +16,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
-    android:layout_height="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingRight="2dp"
+    android:paddingBottom="@dimen/option_bottom_margin"
     android:orientation="vertical">
 
     <TextView
diff --git a/res/values-land/bools.xml b/res/values-land/bools.xml
new file mode 100644
index 0000000..409538d
--- /dev/null
+++ b/res/values-land/bools.xml
@@ -0,0 +1,20 @@
+<?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>
+    <bool name="use_grid_for_options">true</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
new file mode 100644
index 0000000..ecb78be
--- /dev/null
+++ b/res/values-land/dimens.xml
@@ -0,0 +1,25 @@
+<?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="preview_page_gap">93dp</dimen>
+    <dimen name="preview_page_horizontal_margin">92dp</dimen>
+
+    <dimen name="options_container_width">400dp</dimen>
+
+    <dimen name="option_bottom_margin">8dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/res/values/bools.xml b/res/values/bools.xml
new file mode 100644
index 0000000..078b50c
--- /dev/null
+++ b/res/values/bools.xml
@@ -0,0 +1,20 @@
+<?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>
+    <bool name="use_grid_for_options">false</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 30123ed..121a23f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -40,6 +40,7 @@
 
     <!-- Dimensions for the customization option tiles -->
     <dimen name="options_container_height">100dp</dimen>
+    <dimen name="options_container_width">0dp</dimen>
     <dimen name="option_tile_width">72dp</dimen>
     <dimen name="theme_option_icon_sample_height">18dp</dimen>
     <dimen name="theme_option_icon_sample_width">18dp</dimen>
@@ -52,11 +53,13 @@
     <dimen name="theme_option_add_size">32dp</dimen>
     <dimen name="option_tile_padding_vertical">12dp</dimen>
     <dimen name="option_tile_padding_horizontal">10dp</dimen>
+
+    <dimen name="option_bottom_margin">8dp</dimen>
     <!-- Note, using dp instead of sp as this text is more like a "snapshot" of the font -->
     <dimen name="theme_option_font_text_size">16dp</dimen>
     <dimen name="theme_option_title_font_text_size">12sp</dimen>
 
-    <dimen name="option_tile_margin_horizontal">4dp</dimen>
+    <dimen name="option_tile_margin_horizontal">2dp</dimen>
     <dimen name="theme_option_label_margin">4dp</dimen>
 
     <dimen name="preview_card_corner_radius">8dp</dimen>
diff --git a/src/com/android/customization/model/grid/GridOptionsManager.java b/src/com/android/customization/model/grid/GridOptionsManager.java
index 918c6cc..ba5968e 100644
--- a/src/com/android/customization/model/grid/GridOptionsManager.java
+++ b/src/com/android/customization/model/grid/GridOptionsManager.java
@@ -23,6 +23,7 @@
 import com.android.customization.model.CustomizationManager;
 import com.android.customization.module.ThemesUserEventLogger;
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -77,7 +78,8 @@
         @Override
         protected void onPostExecute(List<GridOption> gridOptions) {
             if (mCallback != null) {
-                mCallback.onOptionsLoaded(gridOptions);
+                mCallback.onOptionsLoaded(gridOptions != null ? gridOptions
+                        : Collections.emptyList());
             }
         }
     }
diff --git a/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java b/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java
index d0b8d01..7c7f8d4 100644
--- a/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java
+++ b/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java
@@ -27,6 +27,7 @@
 import android.net.Uri;
 import android.text.TextUtils;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
 import com.android.customization.model.ResourceConstants;
@@ -82,6 +83,7 @@
      * @param reload whether to reload grid options if they're cached.
      */
     @WorkerThread
+    @Nullable
     List<GridOption> fetch(boolean reload) {
         if (!areGridsAvailable()) {
             return null;
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index b311abe..9ec3ad9 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -23,7 +23,9 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
 import android.view.WindowManager;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -71,7 +73,8 @@
     private CustomizationOption mAppliedOption;
 
     public OptionSelectorController(RecyclerView container, List<T> options) {
-        this(container, options, false, true);
+        this(container, options, container.getResources().getBoolean(R.bool.use_grid_for_options),
+                true);
     }
 
     public OptionSelectorController(RecyclerView container, List<T> options,
@@ -143,9 +146,11 @@
             @Override
             public void onBindViewHolder(@NonNull TileViewHolder holder, int position) {
                 CustomizationOption option = mOptions.get(position);
-                if (mSelectedOption == null && option.isActive(manager)) {
-                    mSelectedOption = option;
+                if (option.isActive(manager)) {
                     mAppliedOption = option;
+                    if (mSelectedOption == null) {
+                        mSelectedOption = option;
+                    }
                 }
                 if (holder.labelView != null) {
                     holder.labelView.setText(option.getTitle());
@@ -170,9 +175,12 @@
                     checkedFrame.setLayerGravity(idx, Gravity.BOTTOM | Gravity.RIGHT);
                     checkedFrame.setLayerWidth(idx, checkSize);
                     checkedFrame.setLayerHeight(idx, checkSize);
-                    checkedFrame.setLayerInsetBottom(idx, checkSize/2);
-                    checkedFrame.setLayerInsetLeft(idx, checkSize/2);
+                    checkedFrame.setLayerInsetBottom(idx,
+                            holder.itemView.getPaddingBottom() - (checkSize/3));
+                    checkedFrame.setLayerInsetLeft(idx, checkSize/3);
                     holder.itemView.setForeground(checkedFrame);
+                } else if (mShowCheckmark) {
+                    holder.itemView.setForeground(null);
                 }
             }
 
@@ -189,16 +197,22 @@
 
         // Measure RecyclerView to get to the total amount of space used by all options.
         mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
-        DisplayMetrics metrics = new DisplayMetrics();
-        // TODO: retrieve fixed container width for landscape
-        mContainer.getContext().getSystemService(WindowManager.class)
-                .getDefaultDisplay().getMetrics(metrics);
+        int fixWidth = res.getDimensionPixelSize(R.dimen.options_container_width);
+        int availableWidth;
+        if (fixWidth == 0) {
+            DisplayMetrics metrics = new DisplayMetrics();
+            mContainer.getContext().getSystemService(WindowManager.class)
+                    .getDefaultDisplay().getMetrics(metrics);
+            availableWidth = metrics.widthPixels;
+        } else {
+            availableWidth = fixWidth;
+        }
         int totalWidth = mContainer.getMeasuredWidth();
 
         if (mUseGrid) {
             int numColumns = res.getInteger(R.integer.options_grid_num_columns);
             int widthPerItem = totalWidth / mAdapter.getItemCount();
-            int extraSpace = metrics.widthPixels - widthPerItem * numColumns;
+            int extraSpace = availableWidth - widthPerItem * numColumns;
             int containerSidePadding = extraSpace / (numColumns + 1);
             mContainer.setLayoutManager(new GridLayoutManager(mContainer.getContext(), numColumns));
             mContainer.setPaddingRelative(containerSidePadding, 0, containerSidePadding, 0);
@@ -206,7 +220,7 @@
             return;
         }
 
-        int extraSpace = metrics.widthPixels - totalWidth;
+        int extraSpace = availableWidth - totalWidth;
         if (extraSpace >= 0) {
             mContainer.setOverScrollMode(View.OVER_SCROLL_NEVER);
         }
diff --git a/src/com/android/customization/widget/PreviewPager.java b/src/com/android/customization/widget/PreviewPager.java
index 9ce9d90..eea4c65 100644
--- a/src/com/android/customization/widget/PreviewPager.java
+++ b/src/com/android/customization/widget/PreviewPager.java
@@ -88,13 +88,14 @@
                     res.getDimensionPixelOffset(R.dimen.preview_page_bottom_margin));
         } else if (mPageStyle == STYLE_ASPECT_RATIO) {
             DisplayMetrics dm = res.getDisplayMetrics();
-            mScreenAspectRatio = (float) dm.heightPixels / dm.widthPixels;
+            mScreenAspectRatio = dm.heightPixels > dm.widthPixels
+                    ? (float) dm.heightPixels / dm.widthPixels
+                    : (float) dm.widthPixels / dm.heightPixels;
             mViewPager.setPadding(
                     0,
                     res.getDimensionPixelOffset(R.dimen.preview_page_top_margin),
                     0,
                     res.getDimensionPixelOffset(R.dimen.preview_page_bottom_margin));
-
         }
         mPageIndicator = findViewById(R.id.page_indicator);
         mPreviousArrow = findViewById(R.id.arrow_previous);
@@ -113,10 +114,12 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        if (mPageStyle == STYLE_ASPECT_RATIO && mViewPager.getPaddingStart() == 0) {
+        if (mPageStyle == STYLE_ASPECT_RATIO && mViewPager.getMeasuredWidth() == 0) {
             int availableWidth = MeasureSpec.getSize(widthMeasureSpec);
             int availableHeight = MeasureSpec.getSize(heightMeasureSpec);
-            int indicatorHeight = ((View) mPageIndicator.getParent()).getLayoutParams().height;
+            int indicatorHeight = mPageIndicator.getVisibility() == VISIBLE
+                    ? ((View) mPageIndicator.getParent()).getLayoutParams().height
+                    : 0;
             int pagerHeight = availableHeight - indicatorHeight;
             if (availableWidth > 0) {
                 int absoluteCardWidth = (int) ((pagerHeight - mViewPager.getPaddingBottom()