Change toolbar color dynamically based on scroll offset for S.

Bug: 192600648
Test: manual
Change-Id: Ia4c80856c0e345be3f7614cfe6923daf8eb56db1
diff --git a/res/values-v31/dimens.xml b/res/values-v31/dimens.xml
new file mode 100644
index 0000000..15a7814
--- /dev/null
+++ b/res/values-v31/dimens.xml
@@ -0,0 +1,19 @@
+<!--
+  ~ 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.
+  -->
+<resources>
+    <dimen name="action_bar_elevation">0dp</dimen>
+    <dimen name="action_bar_margin">0dp</dimen>
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 1a4d3bc..9828762 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -52,4 +52,5 @@
 
     <color name="list_divider_color">#1f000000</color>
     <color name="list_item_selected_background_color">?android:colorSecondary</color>
+    <color name="color_surface_header">@color/app_background_color</color>
 </resources>
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
index 0b334d2..31b3747 100644
--- a/res/values/overlayable.xml
+++ b/res/values/overlayable.xml
@@ -41,6 +41,7 @@
             <!-- START COLOR -->
             <item type="color" name="primary"/>
             <item type="color" name="list_item_selected_background_color"/>
+            <item type="color" name="color_surface_header"/>
             <!-- END COLOR -->
 
             <!-- START DIMEN -->
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 5efb9a9..b4ab5bd 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -167,6 +167,11 @@
 
         mNavigator = new NavigationViewManager(this, mDrawer, mState, this, breadcrumb,
                 profileTabsContainer, DocumentsApplication.getUserIdManager(this));
+        AppBarLayout appBarLayout = findViewById(R.id.app_bar);
+        if (appBarLayout != null) {
+            appBarLayout.addOnOffsetChangedListener(mNavigator);
+        }
+
         SearchManagerListener searchListener = new SearchManagerListener() {
             /**
              * Called when search results changed. Refreshes the content of the directory. It
diff --git a/src/com/android/documentsui/NavigationViewManager.java b/src/com/android/documentsui/NavigationViewManager.java
index b09b3c0..83979ab 100644
--- a/src/com/android/documentsui/NavigationViewManager.java
+++ b/src/com/android/documentsui/NavigationViewManager.java
@@ -19,20 +19,27 @@
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Outline;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewOutlineProvider;
+import android.view.Window;
+import android.view.WindowManager;
 import android.widget.FrameLayout;
 
+import androidx.annotation.ColorRes;
 import androidx.annotation.Nullable;
 import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
 
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.base.UserId;
 import com.android.documentsui.dirlist.AnimationView;
+import com.android.documentsui.util.VersionUtils;
 
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
@@ -42,12 +49,13 @@
 /**
  * A facade over the portions of the app and drawer toolbars.
  */
-public class NavigationViewManager {
+public class NavigationViewManager implements AppBarLayout.OnOffsetChangedListener {
 
     private static final String TAG = "NavigationViewManager";
 
     private final DrawerController mDrawer;
     private final Toolbar mToolbar;
+    private final BaseActivity mActivity;
     private final View mHeader;
     private final State mState;
     private final NavigationViewManager.Environment mEnv;
@@ -61,6 +69,7 @@
     private final boolean mShowSearchBar;
 
     private boolean mIsActionModeActivated = false;
+    private @ColorRes int mDefaultStatusBarColorResId;
 
     public NavigationViewManager(
             BaseActivity activity,
@@ -71,6 +80,7 @@
             View tabLayoutContainer,
             UserIdManager userIdManager) {
 
+        mActivity = activity;
         mToolbar = activity.findViewById(R.id.toolbar);
         mHeader = activity.findViewById(R.id.directory_header);
         mDrawer = drawer;
@@ -93,6 +103,15 @@
         mDefaultOutlineProvider = mToolbar.getOutlineProvider();
         mShowSearchBar = activity.getResources().getBoolean(R.bool.show_search_bar);
 
+        final int[] styledAttrs = {android.R.attr.statusBarColor};
+        TypedArray a = mActivity.obtainStyledAttributes(styledAttrs);
+        mDefaultStatusBarColorResId = a.getResourceId(0, -1);
+        if (mDefaultStatusBarColorResId == -1) {
+            Log.w(TAG, "Retrieve statusBarColorResId from theme failed, assigned default");
+            mDefaultStatusBarColorResId = R.color.app_background_color;
+        }
+        a.recycle();
+
         final Resources resources = mToolbar.getResources();
         final int radius = resources.getDimensionPixelSize(R.dimen.search_bar_radius);
         final int marginStart =
@@ -108,6 +127,36 @@
         };
     }
 
+    @Override
+    public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
+        if (!VersionUtils.isAtLeastS()) {
+            return;
+        }
+
+        // For S+ Only. Change toolbar color dynamically based on scroll offset.
+        // Usually this can be done in xml using app:contentScrim and app:statusBarScrim, however
+        // in our case since we also put directory_header.xml inside the CollapsingToolbarLayout,
+        // the scrim will also cover the directory header. Long term need to think about how to
+        // move directory_header out of the AppBarLayout.
+
+        Window window = mActivity.getWindow();
+        View actionBar = window.getDecorView().findViewById(R.id.action_mode_bar);
+        int dynamicHeaderColor = ContextCompat.getColor(mActivity,
+                offset == 0 ? mDefaultStatusBarColorResId : R.color.color_surface_header);
+        if (actionBar != null) {
+            // Action bar needs to be updated separately for selection mode.
+            actionBar.setBackgroundColor(dynamicHeaderColor);
+        }
+
+        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+        window.setStatusBarColor(dynamicHeaderColor);
+        if (shouldShowSearchBar()) {
+            // Do not change search bar background.
+        } else {
+            mToolbar.setBackground(new ColorDrawable(dynamicHeaderColor));
+        }
+    }
+
     public void setSearchBarClickListener(View.OnClickListener listener) {
         mSearchBarView.setOnClickListener(listener);
     }