Merge "Add title and icon in panel header"
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index abe8f41..7a60dad 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -27,6 +27,51 @@
         android:layout_height="wrap_content"
         android:orientation="vertical">
 
+        <LinearLayout
+            android:id="@+id/panel_header"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="start|center_vertical"
+            android:orientation="horizontal"
+            android:visibility="gone">
+
+            <LinearLayout
+                android:layout_width="49dp"
+                android:layout_height="49dp"
+                android:gravity="center_vertical|center_horizontal"
+                android:orientation="horizontal"
+                android:layout_marginStart="10dp">
+                <ImageView
+                    android:id="@+id/title_icon"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="25dp"
+                android:gravity="center_vertical"
+                android:orientation="vertical"
+                android:paddingBottom="9dp"
+                android:paddingTop="9dp">
+                <TextView
+                    android:id="@+id/header_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="?android:attr/textColorPrimary"
+                    android:textSize="20sp"/>
+
+                <TextView
+                    android:id="@+id/header_subtitle"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:ellipsize="end"
+                    android:maxLines="1" />
+
+            </LinearLayout>
+        </LinearLayout>
+
         <TextView
             android:id="@+id/panel_title"
             android:layout_width="match_parent"
diff --git a/src/com/android/settings/panel/PanelContent.java b/src/com/android/settings/panel/PanelContent.java
index 496bac3..de3dc89 100644
--- a/src/com/android/settings/panel/PanelContent.java
+++ b/src/com/android/settings/panel/PanelContent.java
@@ -29,6 +29,20 @@
 public interface PanelContent extends Instrumentable {
 
     /**
+     * @return a icon resource for the title of the Panel.
+     */
+    default int getIcon() {
+        return -1;
+    }
+
+    /**
+     * @return a string for the subtitle of the Panel.
+     */
+    default CharSequence getSubTitle() {
+        return null;
+    }
+
+    /**
      * @return a string for the title of the Panel.
      */
     CharSequence getTitle();
diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java
index 0eda36f..db01a28 100644
--- a/src/com/android/settings/panel/PanelFragment.java
+++ b/src/com/android/settings/panel/PanelFragment.java
@@ -32,6 +32,8 @@
 import android.view.ViewTreeObserver;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -77,15 +79,19 @@
      */
     private static final int DURATION_SLICE_BINDING_TIMEOUT_MS = 250;
 
-    private View mLayoutView;
+    @VisibleForTesting
+    View mLayoutView;
     private TextView mTitleView;
     private Button mSeeMoreButton;
     private Button mDoneButton;
     private RecyclerView mPanelSlices;
-
     private PanelContent mPanel;
     private MetricsFeatureProvider mMetricsProvider;
     private String mPanelClosedKey;
+    private LinearLayout mPanelHeader;
+    private ImageView mTitleIcon;
+    private TextView mHeaderTitle;
+    private TextView mHeaderSubtitle;
 
     private final Map<Uri, LiveData<Slice>> mSliceLiveData = new LinkedHashMap<>();
 
@@ -155,6 +161,10 @@
         mSeeMoreButton = mLayoutView.findViewById(R.id.see_more);
         mDoneButton = mLayoutView.findViewById(R.id.done);
         mTitleView = mLayoutView.findViewById(R.id.panel_title);
+        mPanelHeader = mLayoutView.findViewById(R.id.panel_header);
+        mTitleIcon = mLayoutView.findViewById(R.id.title_icon);
+        mHeaderTitle = mLayoutView.findViewById(R.id.header_title);
+        mHeaderSubtitle = mLayoutView.findViewById(R.id.header_subtitle);
 
         // Make the panel layout gone here, to avoid janky animation when updating from old panel.
         // We will make it visible once the panel is ready to load.
@@ -182,7 +192,16 @@
         // Start loading Slices. When finished, the Panel will animate in.
         loadAllSlices();
 
-        mTitleView.setText(mPanel.getTitle());
+        final int iconRes = mPanel.getIcon();
+        if (iconRes == -1) {
+            mTitleView.setText(mPanel.getTitle());
+        } else {
+            mTitleView.setVisibility(View.GONE);
+            mPanelHeader.setVisibility(View.VISIBLE);
+            mTitleIcon.setImageResource(iconRes);
+            mHeaderTitle.setText(mPanel.getTitle());
+            mHeaderSubtitle.setText(mPanel.getSubTitle());
+        }
         mSeeMoreButton.setOnClickListener(getSeeMoreListener());
         mDoneButton.setOnClickListener(getCloseListener());
 
diff --git a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java
index 8f54115..3b4d2c4 100644
--- a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java
+++ b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java
@@ -40,6 +40,27 @@
 
     public static final Intent INTENT = new Intent();
 
+    private CharSequence mSubTitle;
+    private int mIconRes = -1;
+
+    @Override
+    public int getIcon() {
+        return mIconRes;
+    }
+
+    @Override
+    public CharSequence getSubTitle() {
+        return mSubTitle;
+    }
+
+    public void setIcon(int iconRes) {
+        mIconRes = iconRes;
+    }
+
+    public void setSubTitle(CharSequence subTitle) {
+        mSubTitle = subTitle;
+    }
+
     @Override
     public CharSequence getTitle() {
         return TITLE;
diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
index cbeff97..ee4131e 100644
--- a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
@@ -31,6 +31,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.LinearLayout;
+import android.widget.TextView;
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -41,10 +42,15 @@
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+
+import java.util.Objects;
 
 @RunWith(RobolectricTestRunner.class)
 public class PanelFragmentTest {
 
+    private static final String SUBTITLE = "subtitle";
+
     private Context mContext;
     private PanelFragment mPanelFragment;
     private FakeSettingsPanelActivity mActivity;
@@ -141,4 +147,38 @@
                 0
         );
     }
+
+    @Test
+    public void supportIcon_displayIconHeaderLayout() {
+        mFakePanelContent.setIcon(R.drawable.ic_android);
+        mFakePanelContent.setSubTitle(SUBTITLE);
+        final ActivityController<FakeSettingsPanelActivity> activityController =
+                Robolectric.buildActivity(FakeSettingsPanelActivity.class);
+        activityController.setup();
+        final PanelFragment panelFragment = (PanelFragment)
+                Objects.requireNonNull(activityController
+                        .get()
+                        .getSupportFragmentManager()
+                        .findFragmentById(R.id.main_content));
+        final View titleView = panelFragment.mLayoutView.findViewById(R.id.panel_title);
+        final LinearLayout panelHeader = panelFragment.mLayoutView.findViewById(R.id.panel_header);
+        final TextView headerTitle = panelFragment.mLayoutView.findViewById(R.id.header_title);
+        final TextView headerSubtitle = panelFragment.mLayoutView.findViewById(
+                R.id.header_subtitle);
+        // Check visibility
+        assertThat(panelHeader.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(titleView.getVisibility()).isEqualTo(View.GONE);
+        // Check content
+        assertThat(headerTitle.getText()).isEqualTo(FakePanelContent.TITLE);
+        assertThat(headerSubtitle.getText()).isEqualTo(SUBTITLE);
+    }
+
+    @Test
+    public void notSupportIcon_displayDefaultHeaderLayout() {
+        final View titleView = mPanelFragment.mLayoutView.findViewById(R.id.panel_title);
+        final View panelHeader = mPanelFragment.mLayoutView.findViewById(R.id.panel_header);
+
+        assertThat(panelHeader.getVisibility()).isEqualTo(View.GONE);
+        assertThat(titleView.getVisibility()).isEqualTo(View.VISIBLE);
+    }
 }
\ No newline at end of file