Merge "Wallpaper preview surface layering" into ub-launcher3-master
diff --git a/res/color/option_title_color.xml b/res/color/option_title_color.xml
new file mode 100644
index 0000000..2809247
--- /dev/null
+++ b/res/color/option_title_color.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_activated="true"
+        android:color="?android:colorAccent" />
+    <item
+        android:state_activated="false"
+        android:alpha="0.54"
+        android:color="?android:colorForeground" />
+    <item
+        android:color="?android:colorForeground"/>
+</selector>
diff --git a/res/drawable/bottom_sheet_background.xml b/res/drawable/bottom_sheet_background.xml
new file mode 100644
index 0000000..38214fb
--- /dev/null
+++ b/res/drawable/bottom_sheet_background.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+     Copyright (C) 2020 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="?android:colorPrimary"/>
+    <corners
+        android:bottomLeftRadius="0dp"
+        android:bottomRightRadius="0dp"
+        android:topLeftRadius="@dimen/preview_bottom_sheet_corner_radius"
+        android:topRightRadius="@dimen/preview_bottom_sheet_corner_radius"/>
+</shape>
\ No newline at end of file
diff --git a/res/layout/bottom_action_bar.xml b/res/layout/bottom_action_bar.xml
index 08ee249..fa8d2ea 100644
--- a/res/layout/bottom_action_bar.xml
+++ b/res/layout/bottom_action_bar.xml
@@ -13,12 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.wallpaper.widget.BottomActionBar xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.wallpaper.widget.BottomActionBar
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/bottom_actionbar"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/bottom_navbar_height"
+    android:layout_height="wrap_content"
     android:layout_gravity="bottom"
-    android:background="?android:colorPrimary"
-    android:clickable="true"
     android:elevation="@dimen/bottom_action_bar_elevation"
     android:visibility="gone" />
diff --git a/res/layout/bottom_action_bar_preview_info.xml b/res/layout/bottom_action_bar_preview_info.xml
new file mode 100644
index 0000000..6baf5fb
--- /dev/null
+++ b/res/layout/bottom_action_bar_preview_info.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+     Copyright (C) 2020 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:id="@+id/page_info"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="vertical"
+    android:paddingHorizontal="@dimen/preview_attribution_pane_horizontal_padding"
+    android:paddingVertical="@dimen/bottom_action_bar_padding_vertical"
+    android:theme="@style/WallpaperPicker.BottomPaneStyle">
+
+  <TextView
+      android:id="@+id/preview_attribution_pane_title"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:minHeight="@dimen/preview_attribution_pane_title_height"
+      android:ellipsize="end"
+      android:gravity="center"
+      android:lineHeight="24dp"
+      android:singleLine="true"
+      android:textAppearance="@style/TitleTextAppearance"
+      android:textColor="@color/action_bar_bottom_sheet_text_color"/>
+
+  <TextView
+      android:id="@+id/preview_attribution_pane_subtitle1"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center"
+      android:layout_marginTop="@dimen/preview_attribution_pane_inner_spacer_height"
+      android:textAppearance="@style/SubtitleTextAppearance"
+      android:textColor="@color/action_bar_bottom_sheet_text_color"
+      android:lineHeight="16dp"
+      android:visibility="gone"/>
+
+  <TextView
+      android:id="@+id/preview_attribution_pane_subtitle2"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center_horizontal"
+      android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"
+      android:textSize="14dp"
+      android:lineHeight="16dp"
+      android:textColor="@color/action_bar_bottom_sheet_text_color"
+      android:visibility="gone"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/bottom_actions_layout.xml b/res/layout/bottom_actions_layout.xml
index e858a5c..14bea38 100644
--- a/res/layout/bottom_actions_layout.xml
+++ b/res/layout/bottom_actions_layout.xml
@@ -13,56 +13,83 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<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:paddingHorizontal="@dimen/bottom_action_bar_padding_horizontal"
-    android:theme="@style/BottomActionItemStyle">
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
 
-    <ImageView
-        android:id="@+id/action_cancel"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:src="@drawable/ic_close_gm2_24px"
-        app:layout_constraintEnd_toStartOf="@id/action_rotation"
-        app:layout_constraintHorizontal_chainStyle="spread_inside"
-        app:layout_constraintStart_toStartOf="parent" />
+    <!--  Bottom Sheet  -->
+    <androidx.coordinatorlayout.widget.CoordinatorLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <!-- Bottom sheet view should be a child view of CoordinatorLayout -->
+        <FrameLayout
+            android:id="@+id/action_bottom_sheet"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@drawable/bottom_sheet_background"
+            android:theme="@style/WallpaperPicker.BottomPaneStyle"
+            app:behavior_peekHeight="@dimen/preview_attribution_pane_collapsed_height"
+            app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
+            <include layout="@layout/bottom_action_bar_preview_info"/>
+        </FrameLayout>
+    </androidx.coordinatorlayout.widget.CoordinatorLayout>
 
-    <ImageView
-        android:id="@+id/action_rotation"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:src="@drawable/ic_rotation_gm2_24px"
-        android:visibility="gone"
-        app:layout_constraintEnd_toStartOf="@id/action_information"
-        app:layout_constraintStart_toEndOf="@id/action_cancel" />
+    <!--  Bottom Tabs  -->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/bottom_navbar_height"
+        android:paddingHorizontal="@dimen/bottom_action_bar_padding_horizontal"
+        android:clickable="true"
+        android:background="?android:colorPrimary"
+        android:theme="@style/BottomActionItemStyle">
 
-    <ImageView
-        android:id="@+id/action_information"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:src="@drawable/ic_info_gm2_24px"
-        android:visibility="gone"
-        app:layout_constraintEnd_toStartOf="@id/action_edit"
-        app:layout_constraintStart_toEndOf="@id/action_rotation" />
+        <ImageView
+            android:id="@+id/action_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_close_gm2_24px"
+            app:layout_constraintEnd_toStartOf="@id/action_rotation"
+            app:layout_constraintHorizontal_chainStyle="spread_inside"
+            app:layout_constraintStart_toStartOf="parent" />
 
-    <ImageView
-        android:id="@+id/action_edit"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:src="@drawable/ic_mode_edit_gm2_24px"
-        android:visibility="gone"
-        app:layout_constraintEnd_toStartOf="@id/action_apply"
-        app:layout_constraintStart_toEndOf="@id/action_information" />
+        <ImageView
+            android:id="@+id/action_rotation"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_rotation_gm2_24px"
+            android:visibility="gone"
+            app:layout_constraintEnd_toStartOf="@id/action_information"
+            app:layout_constraintStart_toEndOf="@id/action_cancel" />
 
-    <ImageView
-        android:id="@+id/action_apply"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:src="@drawable/ic_done_gm2_24px"
-        android:visibility="gone"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@id/action_edit" />
+        <ImageView
+            android:id="@+id/action_information"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_info_gm2_24px"
+            android:visibility="gone"
+            app:layout_constraintEnd_toStartOf="@id/action_edit"
+            app:layout_constraintStart_toEndOf="@id/action_rotation" />
 
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+        <ImageView
+            android:id="@+id/action_edit"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_mode_edit_gm2_24px"
+            android:visibility="gone"
+            app:layout_constraintEnd_toStartOf="@id/action_apply"
+            app:layout_constraintStart_toEndOf="@id/action_information" />
+
+        <ImageView
+            android:id="@+id/action_apply"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_done_gm2_24px"
+            android:visibility="gone"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/action_edit" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</LinearLayout>
diff --git a/res/layout/fragment_category_selector.xml b/res/layout/fragment_category_selector.xml
index 2e83774..6f74eb4 100644
--- a/res/layout/fragment_category_selector.xml
+++ b/res/layout/fragment_category_selector.xml
@@ -21,7 +21,6 @@
     android:clipToPadding="false"
     android:fitsSystemWindows="true"
     android:paddingHorizontal="@dimen/grid_edge_space"
-    android:paddingTop="@dimen/grid_padding"
     android:scrollbarSize="@dimen/grid_padding"
     android:scrollbarStyle="outsideOverlay"
     android:scrollbarThumbVertical="@color/scrollbar_thumb_color_dark"
diff --git a/res/layout/grid_item_category.xml b/res/layout/grid_item_category.xml
index 026f694..3953153 100755
--- a/res/layout/grid_item_category.xml
+++ b/res/layout/grid_item_category.xml
@@ -27,17 +27,14 @@
         android:id="@+id/category_title"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_weight="1"
+        android:layout_marginTop="@dimen/grid_item_category_label_padding_top"
+        android:layout_marginBottom="@dimen/grid_item_category_label_padding_bottom"
         android:background="@color/category_title_scrim_color"
         android:ellipsize="end"
-        android:gravity="center_horizontal|bottom"
+        android:gravity="center"
         android:maxLines="1"
-        android:paddingTop="@dimen/grid_item_category_label_padding_top"
-        android:paddingBottom="@dimen/grid_item_category_label_padding_bottom"
-        android:textAlignment="center"
-        android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"
-        android:textColor="@color/category_title_text_color"
-        android:textSize="@dimen/abc_text_size_subhead_material"
+        android:minHeight="@dimen/grid_item_category_label_minimum_height"
+        android:textAppearance="@style/OptionTitleTextAppearance"
         tools:text="Wallpaper category" />
 
     <androidx.cardview.widget.CardView
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 33dcd28..25d083e 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -18,4 +18,5 @@
 <resources>
     <color name="preview_pager_background">@color/google_grey900</color>
     <color name="edit_background_base">@color/material_white_100</color>
+    <color name="action_bar_bottom_sheet_text_color">@color/material_white_100</color>
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ef9faa5..c8599c9 100755
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -41,4 +41,5 @@
     <color name="google_grey700">#5f6368</color>
     <color name="edit_background_base">@color/google_grey700</color>
     <color name="option_border_default">@color/edit_background_base</color>
+    <color name="action_bar_bottom_sheet_text_color">@color/black_87_alpha</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index af6442c..b43d350 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -24,6 +24,7 @@
     <dimen name="grid_item_category_label_padding">12dp</dimen>
     <dimen name="grid_item_category_label_padding_top">12dp</dimen>
     <dimen name="grid_item_category_label_padding_bottom">4dp</dimen>
+    <dimen name="grid_item_category_label_minimum_height">16dp</dimen>
     <dimen name="grid_item_category_overlay_icon_margin_bottom">24dp</dimen>
     <dimen name="grid_item_category_title_height">48dp</dimen>
     <dimen name="grid_tile_aspect_height">340dp</dimen>
@@ -209,8 +210,10 @@
     <!-- Dimensions for the bottom bar. -->
     <dimen name="bottom_navbar_height">56dp</dimen>
     <dimen name="bottom_action_bar_padding_horizontal">16dp</dimen>
+    <dimen name="bottom_action_bar_padding_vertical">20dp</dimen>
     <dimen name="bottom_action_bar_elevation">10dp</dimen>
 
     <dimen name="option_border_width">2dp</dimen>
     <dimen name="option_selected_border_width">3dp</dimen>
+    <dimen name="option_title_font_text_size">12sp</dimen>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6d9274b..3cf2dbc 100755
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -222,4 +222,11 @@
         <item name="android:tint">@color/material_grey500</item>
     </style>
 
+    <!-- Option tiles -->
+    <style name="OptionTitleTextAppearance" parent="TitleTextAppearance">
+        <item name="android:textColor">@color/option_title_color</item>
+        <item name="android:textAlignment">center</item>
+        <item name="android:textSize">@dimen/option_title_font_text_size</item>
+    </style>
+
 </resources>
diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
index ca2acdf..4392ca8 100755
--- a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
+++ b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
@@ -17,6 +17,7 @@
 
 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY;
 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.CANCEL;
+import static com.android.wallpaper.widget.BottomActionBar.BottomAction.INFORMATION;
 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.ROTATION;
 
 import android.app.Activity;
@@ -227,7 +228,7 @@
     private BottomActionBar mBottomActionBar;
     private WallpaperSetter mWallpaperSetter;
     private WallpaperPersister mWallpaperPersister;
-    private WallpaperInfo mSelectedWallpaperInfo;
+    @Nullable private WallpaperInfo mSelectedWallpaperInfo;
     private WallpaperInfo mAppliedWallpaperInfo;
 
     public static IndividualPickerFragment newInstance(String collectionId) {
@@ -829,9 +830,9 @@
 
     private void updateBottomActions(boolean hasWallpaperSelected) {
         mBottomActionBar.showActions(
-                hasWallpaperSelected ? EnumSet.of(APPLY) : EnumSet.of(ROTATION));
+                hasWallpaperSelected ? EnumSet.of(APPLY, INFORMATION) : EnumSet.of(ROTATION));
         mBottomActionBar.hideActions(
-                hasWallpaperSelected ? EnumSet.of(ROTATION) : EnumSet.of(APPLY));
+                hasWallpaperSelected ? EnumSet.of(ROTATION) : EnumSet.of(APPLY, INFORMATION));
     }
 
     private void updateThumbnail(WallpaperInfo selectedWallpaperInfo) {
@@ -847,17 +848,26 @@
         }
     }
 
-    private void onWallpaperSelected(@Nullable WallpaperInfo selectedWallpaperInfo) {
-        if (selectedWallpaperInfo == mSelectedWallpaperInfo) {
+    private void onWallpaperSelected(@Nullable WallpaperInfo newSelectedWallpaperInfo) {
+        if (mSelectedWallpaperInfo == newSelectedWallpaperInfo) {
             return;
         }
+        // Update current wallpaper.
         updateActivatedStatus(mSelectedWallpaperInfo == null
                 ? mAppliedWallpaperInfo : mSelectedWallpaperInfo, false);
-        updateActivatedStatus(selectedWallpaperInfo == null
-                ? mAppliedWallpaperInfo : selectedWallpaperInfo, true);
-        updateBottomActions(selectedWallpaperInfo != null);
-        updateThumbnail(selectedWallpaperInfo);
-        mSelectedWallpaperInfo = selectedWallpaperInfo;
+        // Update new selected wallpaper.
+        updateActivatedStatus(newSelectedWallpaperInfo == null
+                ? mAppliedWallpaperInfo : newSelectedWallpaperInfo, true);
+
+        mSelectedWallpaperInfo = newSelectedWallpaperInfo;
+        updateBottomActions(mSelectedWallpaperInfo != null);
+        updateThumbnail(mSelectedWallpaperInfo);
+        // Populate wallpaper info to bottom sheet page.
+        if (mSelectedWallpaperInfo != null) {
+            mBottomActionBar.populateInfoPage(
+                mSelectedWallpaperInfo.getAttributions(getContext()),
+                shouldShowMetadataInPreview(mSelectedWallpaperInfo));
+        }
     }
 
     private void updateActivatedStatus(WallpaperInfo wallpaperInfo, boolean isActivated) {
@@ -893,6 +903,11 @@
         }
     }
 
+    private static boolean shouldShowMetadataInPreview(WallpaperInfo wallpaperInfo) {
+        android.app.WallpaperInfo wallpaperComponent = wallpaperInfo.getWallpaperComponent();
+        return wallpaperComponent == null || wallpaperComponent.getShowMetadataInPreview();
+    }
+
     /**
      * ViewHolder subclass for "daily refresh" tile in the RecyclerView, only shown if rotation is
      * enabled for this category.
diff --git a/src/com/android/wallpaper/widget/BottomActionBar.java b/src/com/android/wallpaper/widget/BottomActionBar.java
index 1ac6031..ee68b81 100644
--- a/src/com/android/wallpaper/widget/BottomActionBar.java
+++ b/src/com/android/wallpaper/widget/BottomActionBar.java
@@ -15,19 +15,30 @@
  */
 package com.android.wallpaper.widget;
 
+import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED;
+import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED;
+
 import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.wallpaper.R;
 
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback;
+
 import java.util.EnumMap;
 import java.util.EnumSet;
+import java.util.List;
 import java.util.Map;
 
 /** A {@code ViewGroup} which provides the specific actions for the user to interact with. */
@@ -39,16 +50,62 @@
     }
 
     private final Map<BottomAction, View> mActionList = new EnumMap<>(BottomAction.class);
+    private final BottomSheetBehavior<ViewGroup> mBottomSheetBehavior;
+    private final TextView mAttributionTitle;
+    private final TextView mAttributionSubtitle1;
+    private final TextView mAttributionSubtitle2;
 
     public BottomActionBar(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
         LayoutInflater.from(context).inflate(R.layout.bottom_actions_layout, this, true);
 
+        mAttributionTitle = findViewById(R.id.preview_attribution_pane_title);
+        mAttributionSubtitle1 = findViewById(R.id.preview_attribution_pane_subtitle1);
+        mAttributionSubtitle2 = findViewById(R.id.preview_attribution_pane_subtitle2);
+
         mActionList.put(BottomAction.CANCEL, findViewById(R.id.action_cancel));
         mActionList.put(BottomAction.ROTATION, findViewById(R.id.action_rotation));
         mActionList.put(BottomAction.INFORMATION, findViewById(R.id.action_information));
         mActionList.put(BottomAction.EDIT, findViewById(R.id.action_edit));
         mActionList.put(BottomAction.APPLY, findViewById(R.id.action_apply));
+
+        ViewGroup bottomSheet = findViewById(R.id.action_bottom_sheet);
+        mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
+        mBottomSheetBehavior.setState(STATE_COLLAPSED);
+
+        // Workaround as we don't have access to bottomDialogCornerRadius, mBottomSheet radii are
+        // set to dialogCornerRadius by default.
+        GradientDrawable bottomSheetBackground = (GradientDrawable) bottomSheet.getBackground();
+        float[] radii = bottomSheetBackground.getCornerRadii();
+        for (int i = 0; i < radii.length; i++) {
+            radii[i]*=2f;
+        }
+        bottomSheetBackground = ((GradientDrawable)bottomSheetBackground.mutate());
+        bottomSheetBackground.setCornerRadii(radii);
+        bottomSheet.setBackground(bottomSheetBackground);
+
+        ImageView informationIcon = findViewById(R.id.action_information);
+        mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetCallback() {
+            @Override
+            public void onStateChanged(@NonNull View bottomSheet, int newState) {
+                if (newState == STATE_COLLAPSED) {
+                    informationIcon.setColorFilter(getContext().getColor(R.color.material_grey500));
+                } else if (newState == STATE_EXPANDED) {
+                    informationIcon.setColorFilter(getContext().getColor(R.color.accent_color));
+                }
+            }
+
+            @Override
+            public void onSlide(@NonNull View bottomSheet, float slideOffset) {}
+        });
+    }
+
+    @Override
+    public void onVisibilityAggregated(boolean isVisible) {
+        super.onVisibilityAggregated(isVisible);
+        if (!isVisible) {
+            mBottomSheetBehavior.setState(STATE_COLLAPSED);
+        }
     }
 
     /**
@@ -67,6 +124,42 @@
         mActionList.forEach((bottomAction, view) -> view.setOnClickListener(null));
     }
 
+    /**
+     * Populates attributions(wallpaper info) to the information page.
+     *
+     * <p>Once get called, the {@link OnClickListener} to show/hide the information page will be
+     * set for the {@code BottomAction.INFORMATION}.
+     */
+    public void populateInfoPage(List<String> attributions, boolean showMetadata) {
+        resetInfoPage();
+
+        // Ensure the ClickListener can work normally if has info been populated, since it could be
+        // removed by #clearActionClickListeners.
+        setActionClickListener(BottomAction.INFORMATION, unused ->
+            mBottomSheetBehavior.setState(mBottomSheetBehavior.getState() == STATE_COLLAPSED
+                ? STATE_EXPANDED
+                : STATE_COLLAPSED
+            )
+        );
+
+        if (attributions.size() > 0 && attributions.get(0) != null) {
+            mAttributionTitle.setText(attributions.get(0));
+        }
+
+        if (showMetadata) {
+            if (attributions.size() > 1 && attributions.get(1) != null) {
+                mAttributionSubtitle1.setVisibility(View.VISIBLE);
+                mAttributionSubtitle1.setText(attributions.get(1));
+            }
+
+            if (attributions.size() > 2 && attributions.get(2) != null) {
+                mAttributionSubtitle2.setVisibility(View.VISIBLE);
+                mAttributionSubtitle2.setText(attributions.get(2));
+            }
+        }
+    }
+
+
     /** Shows {@link BottomActionBar}. */
     public void show() {
         setVisibility(VISIBLE);
@@ -93,6 +186,9 @@
      */
     public void hideActions(EnumSet<BottomAction> actions) {
         showActions(actions, false);
+        if (actions.contains(BottomAction.INFORMATION)) {
+            mBottomSheetBehavior.setState(STATE_COLLAPSED);
+        }
     }
 
     /**
@@ -123,4 +219,14 @@
         actions.forEach(bottomAction ->
                 mActionList.get(bottomAction).setVisibility(show ? VISIBLE : GONE));
     }
+
+    private void resetInfoPage() {
+        mAttributionTitle.setText(null);
+
+        mAttributionSubtitle1.setText(null);
+        mAttributionSubtitle1.setVisibility(GONE);
+
+        mAttributionSubtitle2.setText(null);
+        mAttributionSubtitle2.setVisibility(GONE);
+    }
 }