Change work profile switch to floating button

This is an initial CL to replace the old switch button. This CL only
focusses on introducing the new floating action button:
* Remove the work profile switch
* Add extended floating action button for switching between profiles
* Hide the button in preview mode and when an item is selected
* Hide the button in Album photos view

More specifications will follow soon

Bug: 190727775
Test: manual

Change-Id: I9231a9d13bc5e237feb137ed9c43bd5e933a8e53
Merged-In: I9231a9d13bc5e237feb137ed9c43bd5e933a8e53
(cherry picked from commit 3970fee99898cd4ab20aa8a3bacedf7b833f5c84)
diff --git a/res/drawable/ic_personal_mode.xml b/res/drawable/ic_personal_mode.xml
new file mode 100644
index 0000000..e48a4c8
--- /dev/null
+++ b/res/drawable/ic_personal_mode.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="@color/picker_profile_button_text_and_icon_color">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M19.08,4.92C15.16,1.02 8.82,1.03 4.91,4.93C1.03,8.85 1.03,15.17 4.92,19.08C6.8,20.95 9.35,22 12,22c2.65,0 5.2,-1.05 7.08,-2.92C22.97,15.16 22.98,8.83 19.08,4.92zM6.34,17.66L6.34,17.66c0.86,-0.8 3.22,-2.16 5.67,-2.16c2.45,0 4.64,1.24 5.65,2.16C14.53,20.77 9.48,20.77 6.34,17.66zM18.93,16.03c-3.99,-3.36 -9.82,-3.36 -13.82,0c-1.77,-3.07 -1.38,-7.05 1.22,-9.69c3.13,-3.12 8.21,-3.13 11.34,-0.01C20.23,8.91 20.75,12.88 18.93,16.03zM15,8.99c0,1.66 -1.34,3 -3,3c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3C13.66,5.99 15,7.34 15,8.99z"
+        android:fillType="evenOdd"/>
+</vector>
diff --git a/res/drawable/ic_work_outline.xml b/res/drawable/ic_work_outline.xml
new file mode 100644
index 0000000..9aaca27
--- /dev/null
+++ b/res/drawable/ic_work_outline.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="@color/picker_profile_button_text_and_icon_color">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,6h-4L16,4c0,-1.11 -0.89,-2 -2,-2h-4c-1.11,0 -2,0.89 -2,2v2L4,6c-1.11,0 -1.99,0.89 -1.99,2L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2L22,8c0,-1.11 -0.89,-2 -2,-2zM10,4h4v2h-4L10,4zM20,19L4,19L4,8h16v11z"/>
+</vector>
diff --git a/res/layout/activity_photo_picker.xml b/res/layout/activity_photo_picker.xml
index 8807d35..688b4ec 100644
--- a/res/layout/activity_photo_picker.xml
+++ b/res/layout/activity_photo_picker.xml
@@ -35,14 +35,6 @@
         app:behavior_hideable="true"
         app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
 
-        <Switch
-            android:visibility="gone"
-            android:layout_gravity="end|top"
-            android:text="Work Profile"
-            android:id="@+id/workprofile"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-
         <androidx.fragment.app.FragmentContainerView
             android:id="@+id/fragment_container"
             android:layout_width="match_parent"
@@ -70,10 +62,8 @@
                     android:orientation="horizontal"/>
 
             </androidx.appcompat.widget.Toolbar>
-
         </com.google.android.material.appbar.AppBarLayout>
 
     </FrameLayout>
 
 </androidx.coordinatorlayout.widget.CoordinatorLayout>
-
diff --git a/res/layout/fragment_picker_tab.xml b/res/layout/fragment_picker_tab.xml
index 892e853..fbe6a30 100644
--- a/res/layout/fragment_picker_tab.xml
+++ b/res/layout/fragment_picker_tab.xml
@@ -28,6 +28,22 @@
         android:drawSelectorOnTop="true"
         android:overScrollMode="never"/>
 
+    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+        android:id="@+id/profile_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/picker_profile_button_margin_bottom"
+        android:layout_gravity="bottom|center"
+        android:textAppearance="@style/PickerProfileButton"
+        android:textColor="@color/picker_profile_button_text_and_icon_color"
+        android:text="@string/picker_work_profile"
+        android:visibility="gone"
+        app:backgroundTint="@color/picker_profile_button_background"
+        app:borderWidth="0dp"
+        app:elevation="3dp"
+        app:icon="@drawable/ic_work_outline"
+    />
+
     <FrameLayout
         android:id="@+id/picker_bottom_bar"
         android:layout_width="match_parent"
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 4d7565a..34c2d34 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -28,5 +28,7 @@
     <color name="picker_toolbar_chip_text_color">#E8EAED</color>
     <color name="picker_toolbar_title_color">#FFFFFF</color>
     <color name="picker_message_text_color">#9AA0A6</color>
+    <color name="picker_profile_button_text_and_icon_color">#A8C7FA</color>
+    <color name="picker_profile_button_background">#1F1F1F</color>
 
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index d3def67..bf7b280 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -37,4 +37,8 @@
     <color name="preview_default_blue">#8AB4F8</color>
     <color name="preview_default_grey">#202124</color>
     <color name="preview_default_black">@android:color/black</color>
+
+    <!-- PhotoPicker Preview -->
+    <color name="picker_profile_button_text_and_icon_color">#0B57D0</color>
+    <color name="picker_profile_button_background">#E8F0FE</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c911972..8e6e12f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -65,4 +65,6 @@
     <!-- PhotoPicker Preview text -->
     <dimen name="preview_add_text_size">14sp</dimen>
     <dimen name="preview_deselect_text_size">16sp</dimen>
+    <!-- PhotoPicker Work Profile -->
+    <dimen name="picker_profile_button_margin_bottom">32dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1b93546..92a6c30 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -106,6 +106,10 @@
     <!-- The text of the albums chip on the toolbar for PhotoPicker. [CHAR LIMIT=30] -->
     <string name="picker_albums">Albums</string>
 
+    <!-- The text of the switching work/personal profile in PhotoPicker. [CHAR LIMIT=30] -->
+    <string name="picker_work_profile">Switch to work</string>
+    <string name="picker_personal_profile">Switch to personal</string>
+
     <!-- Text shown on the album item in PhotoPicker. [CHAR LIMIT=30]  -->
     <plurals name="picker_album_item_count">
         <item quantity="one"><xliff:g id="count" example="1">^1</xliff:g> item</item>
diff --git a/res/values/styles_text.xml b/res/values/styles_text.xml
index e89a43e..7842c58 100644
--- a/res/values/styles_text.xml
+++ b/res/values/styles_text.xml
@@ -29,4 +29,8 @@
         <item name="android:textSize">@dimen/picker_chip_text_size</item>
     </style>
 
+    <style name="PickerProfileButton" parent="@android:style/TextAppearance.Material.Button">
+        <item name="android:textAllCaps">false</item>
+    </style>
+
 </resources>
diff --git a/src/com/android/providers/media/photopicker/PhotoPickerActivity.java b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
index f30d870..9043778 100644
--- a/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
+++ b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
@@ -20,8 +20,6 @@
 
 import android.annotation.IntDef;
 import android.app.Activity;
-import android.content.Context;
-import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.Color;
@@ -41,9 +39,6 @@
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 import android.view.WindowInsetsController;
-import android.widget.CompoundButton;
-import android.widget.Switch;
-import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AppCompatActivity;
@@ -51,14 +46,11 @@
 import androidx.lifecycle.ViewModelProvider;
 
 import com.android.providers.media.R;
-import com.android.providers.media.photopicker.data.UserIdManager;
 import com.android.providers.media.photopicker.data.model.Category;
 import com.android.providers.media.photopicker.data.model.Item;
-import com.android.providers.media.photopicker.data.model.UserId;
 import com.android.providers.media.photopicker.ui.AlbumsTabFragment;
 import com.android.providers.media.photopicker.ui.PhotosTabFragment;
 import com.android.providers.media.photopicker.ui.PreviewFragment;
-import com.android.providers.media.photopicker.util.CrossProfileUtils;
 import com.android.providers.media.photopicker.viewmodel.PickerViewModel;
 
 import com.google.android.material.bottomsheet.BottomSheetBehavior;
@@ -91,7 +83,6 @@
     @interface TabChipType {}
 
     private PickerViewModel mPickerViewModel;
-    private UserIdManager mUserIdManager;
     private ViewGroup mTabChipContainer;
     private Chip mPhotosTabChip;
     private Chip mAlbumsTabChip;
@@ -129,11 +120,6 @@
         initBottomSheetBehavior();
         restoreState(savedInstanceState);
 
-        mUserIdManager = mPickerViewModel.getUserIdManager();
-        if (mUserIdManager.isMultiUserProfiles()) {
-            setUpWorkProfileToggleSwitch(findViewById(R.id.workprofile));
-        }
-
         // Save the fragment container layout so that we can adjust the padding based on preview or
         // non-preview mode.
         mFragmentContainerView = findViewById(R.id.fragment_container);
@@ -305,67 +291,6 @@
         }
     }
 
-    private void setUpWorkProfileToggleSwitch(Switch profileSwitch) {
-        // Enable the work profile switch button
-        profileSwitch.setVisibility(View.VISIBLE);
-
-        // Adjust the padding to make the profile switch button appear below toolbar
-        profileSwitch.setPadding(profileSwitch.getPaddingLeft(), mToolbarHeight,
-                profileSwitch.getPaddingRight(), profileSwitch.getPaddingBottom());
-
-        if (mUserIdManager.isManagedUserId()) {
-            profileSwitch.setChecked(true);
-        }
-
-        final Context context = this;
-        profileSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-            @Override
-            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-                if (isChecked) {
-                    Toast.makeText(PhotoPickerActivity.this, "Switching to work profile",
-                            Toast.LENGTH_SHORT).show();
-                    // TODO(b/190024747): Add caching for performance before switching data to and
-                    //  fro work profile
-                    mUserIdManager.setManagedAsCurrentUserProfile();
-
-                } else {
-                    Toast.makeText(PhotoPickerActivity.this, "Switching to personal profile",
-                            Toast.LENGTH_SHORT).show();
-                    // TODO(b/190024747): Add caching for performance before switching data to and
-                    //  fro work profile
-                    mUserIdManager.setPersonalAsCurrentUserProfile();
-                }
-
-                // Cross user checks
-                if (!mUserIdManager.isCurrentUserSelected()) {
-                    final PackageManager packageManager = context.getPackageManager();
-                    // 1. Check if PICK_IMAGES intent is allowed by admin to show cross user content
-                    if (!CrossProfileUtils.isPickImagesIntentAllowedCrossProfileAccess(
-                            packageManager)) {
-                        Log.i(TAG, "Device admin restricts PhotoPicker to show cross profile "
-                                + "content for current user: " + UserId.CURRENT_USER);
-                        // TODO (b/190727775): Show informative error message to the user in UI.
-                        return;
-                    }
-
-                    // 2. Check if work profile is off
-                    if (mUserIdManager.isManagedUserSelected()) {
-                        final UserId currentUserProfileId =
-                                mUserIdManager.getCurrentUserProfileId();
-                        if (!CrossProfileUtils.isMediaProviderAvailable(currentUserProfileId,
-                                    context)) {
-                            Log.i(TAG, "Work Profile is off, please turn work profile on to "
-                                    + "access work profile content");
-                            // TODO (b/190727775): Show work profile turned off, please turn on.
-                            return;
-                        }
-                    }
-                }
-                mPickerViewModel.updateItems();
-            }
-        });
-    }
-
     public void setResultAndFinishSelf() {
         final List<Item> selectedItemList = new ArrayList<>(
                 mPickerViewModel.getSelectedItems().getValue().values());
diff --git a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
index 0dc92ef..1b8121a 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
@@ -118,7 +118,9 @@
 
         if (mIsDefaultCategory) {
             getActivity().setTitle(/* title= */ "");
+            hideProfileButton(/* hide */ false);
         } else {
+            hideProfileButton(/* hide */ true);
             final String categoryName = Category.getCategoryName(getContext(), mCategoryType);
 
             if (TextUtils.isEmpty(categoryName)) {
diff --git a/src/com/android/providers/media/photopicker/ui/TabFragment.java b/src/com/android/providers/media/photopicker/ui/TabFragment.java
index 9cd9647..f7f6277 100644
--- a/src/com/android/providers/media/photopicker/ui/TabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/TabFragment.java
@@ -16,8 +16,10 @@
 package com.android.providers.media.photopicker.ui;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -30,8 +32,13 @@
 
 import com.android.providers.media.R;
 import com.android.providers.media.photopicker.PhotoPickerActivity;
+import com.android.providers.media.photopicker.data.UserIdManager;
+import com.android.providers.media.photopicker.data.model.UserId;
+import com.android.providers.media.photopicker.util.CrossProfileUtils;
 import com.android.providers.media.photopicker.viewmodel.PickerViewModel;
 
+import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
+
 import java.text.NumberFormat;
 import java.util.Locale;
 
@@ -40,10 +47,16 @@
  */
 public abstract class TabFragment extends Fragment {
 
+    private static final String TAG =  "PhotoPickerTabFragment";
+
     protected PickerViewModel mPickerViewModel;
     protected ImageLoader mImageLoader;
     protected AutoFitRecyclerView mRecyclerView;
+
     private int mBottomBarSize;
+    private ExtendedFloatingActionButton mProfileButton;
+    private UserIdManager mUserIdManager;
+    private boolean mHideProfileButton;
 
     @Override
     @NonNull
@@ -56,10 +69,19 @@
     @Override
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
+
         mImageLoader = new ImageLoader(getContext());
         mRecyclerView = view.findViewById(R.id.photo_list);
         mRecyclerView.setHasFixedSize(true);
         mPickerViewModel = new ViewModelProvider(requireActivity()).get(PickerViewModel.class);
+
+        mProfileButton = view.findViewById(R.id.profile_button);
+        mUserIdManager = mPickerViewModel.getUserIdManager();
+        if (mUserIdManager.isMultiUserProfiles()) {
+            mProfileButton.setVisibility(View.VISIBLE);
+            setUpProfileButton();
+        }
+
         final boolean canSelectMultiple = mPickerViewModel.canSelectMultiple();
         if (canSelectMultiple) {
             final Button addButton = view.findViewById(R.id.button_add);
@@ -86,14 +108,97 @@
                     dimen = getBottomGapForRecyclerView(mBottomBarSize);
                 }
                 mRecyclerView.setPadding(0, 0, 0, dimen);
+
+                if (mUserIdManager.isMultiUserProfiles()) {
+                    if (selectedItemList.size() > 0) {
+                        mProfileButton.hide();
+                    } else {
+                        if (!mHideProfileButton) {
+                            mProfileButton.show();
+                        }
+                    }
+                }
             });
         }
     }
 
+    private void setUpProfileButton() {
+        updateProfileIconAndText(mUserIdManager.isManagedUserSelected());
+
+        final Context context = getContext();
+        mProfileButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+
+                // Cross user checks
+                if (mUserIdManager.isCurrentUserSelected()) {
+                    final PackageManager packageManager = context.getPackageManager();
+                    // 1. Check if PICK_IMAGES intent is allowed by admin to show cross user content
+                    if (!CrossProfileUtils.isPickImagesIntentAllowedCrossProfileAccess(
+                            packageManager)) {
+                        // TODO (b/190727775): Show informative error message to the user in UI.
+                        return;
+                    }
+
+                    // 2. Check if work profile is off
+                    if (!mUserIdManager.isManagedUserSelected()) {
+                        final UserId managedUserProfileId =
+                                mUserIdManager.getManagedUserId();
+                        if (!CrossProfileUtils.isMediaProviderAvailable(managedUserProfileId,
+                                context)) {
+                            Log.i(TAG, "Work Profile is off, please turn work profile on to "
+                                    + "access work profile content");
+                            // TODO (b/190727775): Show work profile turned off, please turn on.
+                            return;
+                        }
+                    }
+                }
+
+                if (mUserIdManager.isManagedUserSelected()) {
+                    // TODO(b/190024747): Add caching for performance before switching data to and
+                    //  fro work profile
+                    mUserIdManager.setPersonalAsCurrentUserProfile();
+
+                } else {
+                    // TODO(b/190024747): Add caching for performance before switching data to and
+                    //  fro work profile
+                    mUserIdManager.setManagedAsCurrentUserProfile();
+                }
+
+                updateProfileIconAndText(mUserIdManager.isManagedUserSelected());
+
+                mPickerViewModel.updateItems();
+                mPickerViewModel.updateCategories();
+            }
+        });
+    }
+
+    private void updateProfileIconAndText(boolean isManagedUserSelected) {
+        if (isManagedUserSelected) {
+            mProfileButton.setIconResource(R.drawable.ic_personal_mode);
+            mProfileButton.setText(R.string.picker_personal_profile);
+        } else {
+            mProfileButton.setIconResource(R.drawable.ic_work_outline);
+            mProfileButton.setText(R.string.picker_work_profile);
+        }
+        mProfileButton.setIconTintResource(R.color.picker_profile_button_text_and_icon_color);
+    }
+
     protected int getBottomGapForRecyclerView(int bottomBarSize) {
         return bottomBarSize;
     }
 
+    protected void hideProfileButton(boolean hide) {
+        if (hide) {
+            mProfileButton.hide();
+            mHideProfileButton = true;
+        } else if (!hide && mUserIdManager.isMultiUserProfiles()
+                && mPickerViewModel.getSelectedItems().getValue().size() == 0) {
+            mProfileButton.show();
+            mHideProfileButton = false;
+        }
+    }
+
     private static String generateAddButtonString(Context context, int size) {
         final String sizeString = NumberFormat.getInstance(Locale.getDefault()).format(size);
         final String template = context.getString(R.string.picker_add_button_multi_select);