Update ActionButtonsPreference style

 - Add rounded background
 - Add divider between buttons
 Screenshots:
   https://screenshot.googleplex.com/5b3fanqgpbpufyD.png
   https://screenshot.googleplex.com/5jG85UeVk64pAMg.png

Bug: 187923403
Test: atest ActionButtonsPreferenceTest
Change-Id: I04bebbfc676c5c5d019a4dce1b8e31bfc69360d7
diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
index a19f7af..22b25a3 100644
--- a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
@@ -23,4 +23,15 @@
             column="15"/>
     </issue>
 
+    <issue
+        id="NewApi"
+        message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)"
+        errorLine1="        android:radius=&quot;?android:attr/dialogCornerRadius&quot;"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml"
+            line="23"
+            column="9"/>
+    </issue>
+
 </issues>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml
new file mode 100644
index 0000000..ae3834d
--- /dev/null
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 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"
+       xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+       android:shape="rectangle">
+    <solid android:color="?androidprv:attr/colorSurface" />
+    <corners
+        android:radius="?android:attr/dialogCornerRadius"
+    />
+</shape>
\ No newline at end of file
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml b/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml
new file mode 100644
index 0000000..ba612d7
--- /dev/null
+++ b/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 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="wrap_content"
+    android:layout_margin="8dp"
+    android:paddingHorizontal="8dp"
+    android:orientation="horizontal"
+    android:background="@drawable/settingslib_rounded_background">
+
+    <Button
+        android:id="@+id/button1"
+        style="@style/SettingsLibActionButton"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
+
+    <View
+        android:id="@+id/divider1"
+        android:layout_width="1dp"
+        android:layout_height="match_parent"
+        android:paddingHorizontal="4dp"
+        android:visibility="gone"
+        android:background="?android:colorBackground" />
+
+    <Button
+        android:id="@+id/button2"
+        style="@style/SettingsLibActionButton"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
+
+    <View
+        android:id="@+id/divider2"
+        android:layout_width="1dp"
+        android:layout_height="match_parent"
+        android:paddingHorizontal="4dp"
+        android:visibility="gone"
+        android:background="?android:colorBackground" />
+
+    <Button
+        android:id="@+id/button3"
+        style="@style/SettingsLibActionButton"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
+
+    <View
+        android:id="@+id/divider3"
+        android:layout_width="1dp"
+        android:layout_height="match_parent"
+        android:paddingHorizontal="4dp"
+        android:visibility="gone"
+        android:background="?android:colorBackground" />
+
+    <Button
+        android:id="@+id/button4"
+        style="@style/SettingsLibActionButton"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
+</LinearLayout>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml b/packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml
similarity index 88%
rename from packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml
rename to packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml
index 4f47113..55df34f 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml
@@ -24,29 +24,29 @@
 
     <Button
         android:id="@+id/button1"
-        style="@style/SettingsActionButton"
+        style="@style/SettingsLibActionButton"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"/>
 
     <Button
         android:id="@+id/button2"
-        style="@style/SettingsActionButton"
+        style="@style/SettingsLibActionButton"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"/>
 
     <Button
         android:id="@+id/button3"
-        style="@style/SettingsActionButton"
+        style="@style/SettingsLibActionButton"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"/>
 
     <Button
         android:id="@+id/button4"
-        style="@style/SettingsActionButton"
+        style="@style/SettingsLibActionButton"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
index efa508d..42c7d76 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
@@ -16,11 +16,10 @@
   -->
 
 <resources>
-    <style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
+    <style name="SettingsLibActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
         <item name="android:drawablePadding">4dp</item>
         <item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>
-        <item name="android:layout_marginEnd">8dp</item>
         <item name="android:paddingTop">20dp</item>
         <item name="android:paddingBottom">20dp</item>
     </style>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
index 8b46cc6..aeda7ac 100644
--- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
+++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
@@ -27,16 +27,20 @@
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.StringRes;
+import androidx.core.os.BuildCompat;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * This preference provides a four buttons layout with Settings style.
  * It looks like below
  *
- * --------------------------------------------------
- * button1     | button2   | button3   | button4   |
- * --------------------------------------------------
+ *  ---------------------------------------
+ * - button1 | button2 | button3 | button4 -
+ *  ---------------------------------------
  *
  * User can set title / icon / click listener for each button.
  *
@@ -49,10 +53,16 @@
 public class ActionButtonsPreference extends Preference {
 
     private static final String TAG = "ActionButtonPreference";
+
     private final ButtonInfo mButton1Info = new ButtonInfo();
     private final ButtonInfo mButton2Info = new ButtonInfo();
     private final ButtonInfo mButton3Info = new ButtonInfo();
     private final ButtonInfo mButton4Info = new ButtonInfo();
+    private final List<ButtonInfo> mVisibleButtonInfos = new ArrayList<>(4);
+
+    private View mDivider1;
+    private View mDivider2;
+    private View mDivider3;
 
     public ActionButtonsPreference(Context context, AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
@@ -76,25 +86,49 @@
     }
 
     private void init() {
-        setLayoutResource(R.layout.settings_action_buttons);
+        setLayoutResource(R.layout.settingslib_action_buttons);
         setSelectable(false);
     }
 
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
-        holder.setDividerAllowedAbove(true);
-        holder.setDividerAllowedBelow(true);
+        if (!BuildCompat.isAtLeastS()) {
+            holder.setDividerAllowedAbove(true);
+            holder.setDividerAllowedBelow(true);
+        }
 
         mButton1Info.mButton = (Button) holder.findViewById(R.id.button1);
         mButton2Info.mButton = (Button) holder.findViewById(R.id.button2);
         mButton3Info.mButton = (Button) holder.findViewById(R.id.button3);
         mButton4Info.mButton = (Button) holder.findViewById(R.id.button4);
 
+        mDivider1 = holder.findViewById(R.id.divider1);
+        mDivider2 = holder.findViewById(R.id.divider2);
+        mDivider3 = holder.findViewById(R.id.divider3);
+
         mButton1Info.setUpButton();
         mButton2Info.setUpButton();
         mButton3Info.setUpButton();
         mButton4Info.setUpButton();
+
+        // Add visible button into list only
+        if (mButton1Info.isVisible()) {
+            mVisibleButtonInfos.add(mButton1Info);
+        }
+        if (mButton2Info.isVisible()) {
+            mVisibleButtonInfos.add(mButton2Info);
+        }
+        if (mButton3Info.isVisible()) {
+            mVisibleButtonInfos.add(mButton3Info);
+        }
+        if (mButton4Info.isVisible()) {
+            mVisibleButtonInfos.add(mButton4Info);
+        }
+
+        setupDivider1();
+        setupDivider2();
+        setupDivider3();
     }
 
     /**
@@ -357,6 +391,28 @@
         return this;
     }
 
+    private void setupDivider1() {
+        // Display divider1 only if button1 and button2 is visible
+        if (mDivider1 != null && mButton1Info.isVisible() && mButton2Info.isVisible()) {
+            mDivider1.setVisibility(View.VISIBLE);
+        }
+    }
+
+    private void setupDivider2() {
+        // Display divider2 only if button3 is visible and button2 or button3 is visible
+        if (mDivider2 != null && mButton3Info.isVisible()
+                && (mButton1Info.isVisible() || mButton2Info.isVisible())) {
+            mDivider2.setVisibility(View.VISIBLE);
+        }
+    }
+
+    private void setupDivider3() {
+        // Display divider3 only if button4 is visible and 2 visible buttons at least
+        if (mDivider3 != null && mVisibleButtonInfos.size() > 1 && mButton4Info.isVisible()) {
+            mDivider3.setVisibility(View.VISIBLE);
+        }
+    }
+
     static class ButtonInfo {
         private Button mButton;
         private CharSequence mText;
@@ -379,6 +435,10 @@
             }
         }
 
+        boolean isVisible() {
+            return mButton.getVisibility() == View.VISIBLE;
+        }
+
         /**
          * By default, four buttons are visible.
          * However, there are two cases which button should be invisible.
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
index e24b525..9f31cef 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
@@ -48,7 +48,7 @@
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-        mRootView = View.inflate(mContext, R.layout.settings_action_buttons, null /* parent */);
+        mRootView = View.inflate(mContext, R.layout.settingslib_action_buttons, null /* parent */);
         mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
         mPref = new ActionButtonsPreference(mContext);
     }
@@ -251,6 +251,114 @@
         assertThat(drawablesAroundText[1 /* top */]).isNull();
     }
 
+    @Test
+    public void onBindViewHolder_setAllButton_shouldShowAllDivider() {
+        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton2Text(R.string.install_other_apps);
+        mPref.setButton3Text(R.string.install_other_apps);
+        mPref.setButton4Text(R.string.install_other_apps);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setAllButtonWithoutButton2_shouldHideDivider1() {
+        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton3Text(R.string.install_other_apps);
+        mPref.setButton4Text(R.string.install_other_apps);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setAllButtonWithoutButton3_shouldHideDivider2() {
+        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton2Text(R.string.install_other_apps);
+        mPref.setButton4Text(R.string.install_other_apps);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setButton1And4_shouldShowDivider3Only() {
+        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton4Text(R.string.install_other_apps);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setOneButtonOnly_noDivider() {
+        mPref.setButton4Text(R.string.install_other_apps);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void onBindViewHolder_setButton1And2_shouldShowDivider1Only() {
+        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton2Text(R.string.install_other_apps);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void onBindViewHolder_setButton1And3_shouldShowDivider2Only() {
+        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton3Text(R.string.install_other_apps);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
     public static ActionButtonsPreference createMock() {
         final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
         when(pref.setButton1Text(anyInt())).thenReturn(pref);