Merge "Extend settings panel under navigation bar" into tm-qpr-dev
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index f154abc..fd8d55f 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -20,6 +20,7 @@
     android:id="@+id/panel_container"
     android:layout_width="@dimen/settings_panel_width"
     android:layout_height="wrap_content"
+    android:fitsSystemWindows="true"
     android:layout_gravity="center_horizontal"
     android:background="@drawable/settings_panel_rounded_top_corner_background" >
 
diff --git a/res/values/themes.xml b/res/values/themes.xml
index ff56e7e..e6c0510 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -229,6 +229,7 @@
     <!-- Note that Dialog themes do not set list dividers -->
     <style name="Theme.Panel" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
         <item name="android:windowBackground">@null</item>
+        <item name="android:windowTranslucentNavigation">true</item>
         <item name="android:dividerHorizontal">@*android:drawable/list_divider_material</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:listDivider">@*android:drawable/list_divider_material</item>
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
index 77949eb..60b8f88 100644
--- a/src/com/android/settings/panel/SettingsPanelActivity.java
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -29,12 +29,15 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
 
 /**
@@ -144,9 +147,33 @@
             window.setGravity(Gravity.BOTTOM);
             window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.WRAP_CONTENT);
+            setupNavigationBar();
             mPanelFragment = new PanelFragment();
             mPanelFragment.setArguments(new Bundle(mBundle));
             fragmentManager.beginTransaction().add(R.id.main_content, mPanelFragment).commit();
         }
     }
+
+    /**
+     * Adjust bottom edge and color.
+     */
+    private void setupNavigationBar() {
+        // Extend the panel all the way to the bottom of the screen, as opposed to sitting on top of
+        // the navigation bar.
+        ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(),
+                (v, windowInsets) -> {
+                    v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), 0);
+                    return windowInsets; // propagate down to panel layout root element
+                });
+
+        // When using 3-button navigation in light mode, the system picks white navigation buttons
+        // which are not sufficiently contrasted from the panel background.
+        WindowInsetsControllerCompat windowInsetsController =
+                ViewCompat.getWindowInsetsController(getWindow().getDecorView());
+
+        if (windowInsetsController != null) {
+            boolean forceNavigationButtonsDark = !Utils.isNightMode(this);
+            windowInsetsController.setAppearanceLightNavigationBars(forceNavigationButtonsDark);
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 5cdc12a..ea55b90 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -16,11 +16,13 @@
 
 package com.android.settings.panel;
 
+import static android.content.res.Configuration.UI_MODE_NIGHT_NO;
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -30,15 +32,20 @@
 
 import android.content.res.Configuration;
 import android.os.Build;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
 import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -61,6 +68,9 @@
     private PanelFragment mPanelFragment;
     @Mock
     private FragmentManager mFragmentManager;
+    @Mock
+    private FragmentTransaction mTransaction;
+    private int mOriginalUiMode;
 
     @Before
     public void setUp() {
@@ -76,6 +86,15 @@
         mSettingsPanelActivity.mPanelFragment = mPanelFragment;
         when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment);
         when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
+        mOriginalUiMode = mSettingsPanelActivity.getResources().getConfiguration().uiMode;
+        when(mFragmentManager.beginTransaction()).thenReturn(mTransaction);
+        when(mTransaction.add(anyInt(), any())).thenReturn(mTransaction);
+        when(mTransaction.commit()).thenReturn(0); // don't care about return value
+    }
+
+    @After
+    public void tearDown() {
+        mSettingsPanelActivity.getResources().getConfiguration().uiMode = mOriginalUiMode;
     }
 
     @Test
@@ -179,4 +198,24 @@
 
         verify(mPanelFragment, never()).updatePanelWithAnimation();
     }
+
+    @Test
+    public void onCreated_isWindowBottomPaddingZero() {
+        int paddingBottom = mSettingsPanelActivity.getWindow().getDecorView().getPaddingBottom();
+        assertThat(paddingBottom).isEqualTo(0);
+    }
+
+    @Test
+    public void notInNightMode_lightNavigationBarAppearance() {
+        Configuration config = mSettingsPanelActivity.getResources().getConfiguration();
+        config.uiMode = UI_MODE_NIGHT_NO;
+        mSettingsPanelActivity.onConfigurationChanged(config); // forces creation
+
+        mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent());
+        verify(mFragmentManager).beginTransaction();
+
+        View decorView = mSettingsPanelActivity.getWindow().getDecorView();
+        WindowInsetsControllerCompat controller = ViewCompat.getWindowInsetsController(decorView);
+        assertThat(controller.isAppearanceLightNavigationBars()).isTrue();
+    }
 }