Merge "Add bottom padding of profile group on Bluetooth detail page" into rvc-dev am: 3370e0304f

Change-Id: I0a4539462309be4f24b0fc8cd866c1dfcb2ee6c4
diff --git a/res/layout/preference_bluetooth_profile_category.xml b/res/layout/preference_bluetooth_profile_category.xml
new file mode 100644
index 0000000..8c09bad
--- /dev/null
+++ b/res/layout/preference_bluetooth_profile_category.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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:gravity="center_vertical"
+              android:orientation="horizontal"
+              android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+              android:paddingTop="16dp"
+              android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+</LinearLayout>
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index aa12409..dcaeffe 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -28,6 +28,7 @@
 import androidx.preference.PreferenceScreen;
 import androidx.preference.SwitchPreference;
 
+import com.android.settings.R;
 import com.android.settingslib.bluetooth.A2dpProfile;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -48,6 +49,8 @@
         implements Preference.OnPreferenceClickListener,
         LocalBluetoothProfileManager.ServiceListener {
     private static final String KEY_PROFILES_GROUP = "bluetooth_profiles";
+    private static final String KEY_BOTTOM_PREFERENCE = "bottom_preference";
+    private static final int ORDINAL = 99;
 
     @VisibleForTesting
     static final String HIGH_QUALITY_AUDIO_PREF_TAG = "A2dpProfileHighQualityAudio";
@@ -55,7 +58,9 @@
     private LocalBluetoothManager mManager;
     private LocalBluetoothProfileManager mProfileManager;
     private CachedBluetoothDevice mCachedDevice;
-    private PreferenceCategory mProfilesContainer;
+
+    @VisibleForTesting
+    PreferenceCategory mProfilesContainer;
 
     public BluetoothDetailsProfilesController(Context context, PreferenceFragmentCompat fragment,
             LocalBluetoothManager manager, CachedBluetoothDevice device, Lifecycle lifecycle) {
@@ -69,6 +74,7 @@
     @Override
     protected void init(PreferenceScreen screen) {
         mProfilesContainer = (PreferenceCategory)screen.findPreference(getPreferenceKey());
+        mProfilesContainer.setLayoutResource(R.layout.preference_bluetooth_profile_category);
         // Call refresh here even though it will get called later in onResume, to avoid the
         // list of switches appearing to "pop" into the page.
         refresh();
@@ -283,6 +289,16 @@
                 mProfilesContainer.removePreference(pref);
             }
         }
+
+        Preference preference = mProfilesContainer.findPreference(KEY_BOTTOM_PREFERENCE);
+        if (preference == null) {
+            preference = new Preference(mContext);
+            preference.setLayoutResource(R.layout.preference_bluetooth_profile_category);
+            preference.setEnabled(false);
+            preference.setKey(KEY_BOTTOM_PREFERENCE);
+            preference.setOrder(ORDINAL);
+            mProfilesContainer.addPreference(preference);
+        }
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
index 5fc45a6..c5b0a6a 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
@@ -29,6 +29,7 @@
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 
+import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
 import androidx.preference.SwitchPreference;
 
@@ -84,6 +85,7 @@
         mController = new BluetoothDetailsProfilesController(mContext, mFragment, mLocalManager,
                 mCachedDevice, mLifecycle);
         mProfiles.setKey(mController.getPreferenceKey());
+        mController.mProfilesContainer = mProfiles;
         mScreen.addPreference(mProfiles);
     }
 
@@ -193,11 +195,14 @@
     private List<SwitchPreference> getProfileSwitches(boolean expectOnlyMConnectable) {
         if (expectOnlyMConnectable) {
             assertThat(mConnectableProfiles).isNotEmpty();
-            assertThat(mProfiles.getPreferenceCount()).isEqualTo(mConnectableProfiles.size());
+            assertThat(mProfiles.getPreferenceCount() - 1).isEqualTo(mConnectableProfiles.size());
         }
         List<SwitchPreference> result = new ArrayList<>();
         for (int i = 0; i < mProfiles.getPreferenceCount(); i++) {
-            result.add((SwitchPreference)mProfiles.getPreference(i));
+            final Preference preference = mProfiles.getPreference(i);
+            if (preference instanceof SwitchPreference) {
+                result.add((SwitchPreference) preference);
+            }
         }
         return result;
     }
@@ -236,7 +241,7 @@
         mController.onDeviceAttributesChanged();
 
         // There should have been no new switches added.
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(3);
 
         // Make sure both switches got disabled.
         assertThat(switches.get(0).isEnabled()).isFalse();
@@ -258,7 +263,7 @@
         assertThat(mConnectableProfiles.get(0).isEnabled(mDevice)).isFalse();
 
         // Make sure no new preferences were added.
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(3);
 
         // Clicking the pref again should make the profile once again preferred.
         pref.performClick();
@@ -266,7 +271,7 @@
         assertThat(mConnectableProfiles.get(0).isEnabled(mDevice)).isTrue();
 
         // Make sure we still haven't gotten any new preferences added.
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(3);
     }
 
     @Test
@@ -295,7 +300,7 @@
         assertThat(pref.isChecked()).isTrue();
 
         pref.performClick();
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(1);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
         assertThat(mDevice.getPhonebookAccessPermission())
                 .isEqualTo(BluetoothDevice.ACCESS_REJECTED);
     }
@@ -318,7 +323,7 @@
         assertThat(pref.isChecked()).isFalse();
 
         pref.performClick();
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(1);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
         assertThat(mDevice.getPhonebookAccessPermission())
                 .isEqualTo(BluetoothDevice.ACCESS_ALLOWED);
     }
@@ -340,7 +345,7 @@
         assertThat(pref.isChecked()).isFalse();
 
         pref.performClick();
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(1);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
         assertThat(mDevice.getMessageAccessPermission()).isEqualTo(BluetoothDevice.ACCESS_ALLOWED);
     }
 
@@ -386,7 +391,7 @@
         setupDevice(makeDefaultDeviceConfig());
         addMockA2dpProfile(true, false, false);
         showScreen(mController);
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(1);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
         SwitchPreference pref = (SwitchPreference) mProfiles.getPreference(0);
         assertThat(pref.getKey())
             .isNotEqualTo(BluetoothDetailsProfilesController.HIGH_QUALITY_AUDIO_PREF_TAG);
@@ -408,7 +413,7 @@
         setupDevice(makeDefaultDeviceConfig());
         A2dpProfile audioProfile = addMockA2dpProfile(true, true, true);
         showScreen(mController);
-        assertThat(mProfiles.getPreferenceCount()).isEqualTo(2);
+        assertThat(mProfiles.getPreferenceCount()).isEqualTo(3);
 
         // Disabling media audio should cause the high quality audio switch to disappear, but not
         // the regular audio one.