Add tabChips and support Albums tab

- Add tab chips on toolbar and change icons
- Support transitions between fragments

Test: manual. add videos on bugs
Bug: 191127346
Bug: 191746858
Change-Id: Ie50aa996ebcd45f84cb8e32cb8ef577449c66900
Merged-In: Ie50aa996ebcd45f84cb8e32cb8ef577449c66900
(cherry picked from commit ae8f579bfe3bf8470505ff5c750feac8278126b8)
diff --git a/src/com/android/providers/media/photopicker/PhotoPickerActivity.java b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
index 7f37261..f66195a 100644
--- a/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
+++ b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
@@ -18,18 +18,23 @@
 
 import static com.android.providers.media.photopicker.data.PickerResult.getPickerResponseIntent;
 
+import android.annotation.IntDef;
 import android.app.Activity;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.SystemProperties;
 import android.provider.MediaStore;
+import android.text.TextUtils;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.CompoundButton;
 import android.widget.Switch;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.appcompat.widget.Toolbar;
 import androidx.lifecycle.ViewModelProvider;
@@ -40,10 +45,16 @@
 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.chip.Chip;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -52,20 +63,35 @@
  * app does not get access to all photos/videos.
  */
 public class PhotoPickerActivity extends AppCompatActivity {
+
     private static final String TAG =  "PhotoPickerActivity";
+    private static final String EXTRA_TAB_CHIP_TYPE = "tab_chip_type";
+    private static final int TAB_CHIP_TYPE_PHOTOS = 0;
+    private static final int TAB_CHIP_TYPE_ALBUMS = 1;
+
+    @IntDef(prefix = { "TAB_CHIP_TYPE" }, value = {
+            TAB_CHIP_TYPE_PHOTOS,
+            TAB_CHIP_TYPE_ALBUMS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface TabChipType {}
 
     private PickerViewModel mPickerViewModel;
     private UserIdManager mUserIdManager;
+    private ViewGroup mTabChipContainer;
+    private Chip mPhotosTabChip;
+    private Chip mAlbumsTabChip;
+    @TabChipType
+    private int mSelectedTabChipType;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_photo_picker);
 
-        Toolbar toolbar = findViewById(R.id.toolbar);
+        final Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
-        // TODO (b/185801192): remove this and add tabs Photos and Albums
-        getSupportActionBar().setTitle("Photos & Videos");
+        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
         mPickerViewModel = new ViewModelProvider(this).get(PickerViewModel.class);
         try {
@@ -75,10 +101,9 @@
             setCancelledResultAndFinishSelf();
         }
 
-        // only add the fragment when the activity is created at first time
-        if (savedInstanceState == null) {
-            PhotosTabFragment.show(getSupportFragmentManager(), Category.getDefaultCategory());
-        }
+        mTabChipContainer = findViewById(R.id.chip_container);
+        initTabChips();
+        restoreState(savedInstanceState);
 
         mUserIdManager = mPickerViewModel.getUserIdManager();
         final Switch profileSwitch = findViewById(R.id.workprofile);
@@ -88,6 +113,109 @@
         }
     }
 
+    @Override
+    public boolean onSupportNavigateUp() {
+        onBackPressed();
+        return true;
+    }
+
+    @Override
+    public void setTitle(CharSequence title) {
+        super.setTitle(title);
+        getSupportActionBar().setTitle(title);
+        updateToolbar(TextUtils.isEmpty(title));
+    }
+
+    /**
+     * Called when owning activity is saving state to be used to restore state during creation.
+     *
+     * @param state Bundle to save state
+     */
+    @Override
+    public void onSaveInstanceState(Bundle state) {
+        super.onSaveInstanceState(state);
+        state.putInt(EXTRA_TAB_CHIP_TYPE, mSelectedTabChipType);
+    }
+
+    private void restoreState(Bundle savedInstanceState) {
+        if (savedInstanceState != null) {
+            final int tabChipType = savedInstanceState.getInt(EXTRA_TAB_CHIP_TYPE,
+                    TAB_CHIP_TYPE_PHOTOS);
+            mSelectedTabChipType = tabChipType;
+            if (tabChipType == TAB_CHIP_TYPE_PHOTOS) {
+                if (PreviewFragment.get(getSupportFragmentManager()) == null) {
+                    onTabChipClick(mPhotosTabChip);
+                } else {
+                    // PreviewFragment is shown
+                    mPhotosTabChip.setSelected(true);
+                }
+            } else { // CHIP_TYPE_ALBUMS
+                if (PhotosTabFragment.get(getSupportFragmentManager()) == null) {
+                    onTabChipClick(mAlbumsTabChip);
+                } else {
+                    // PreviewFragment or PhotosTabFragment with category is shown
+                    mAlbumsTabChip.setSelected(true);
+                }
+            }
+        } else {
+            // This is the first launch, set the default behavior. Hide the title, show the chips
+            // and show the PhotosTabFragment
+            setTitle("");
+            onTabChipClick(mPhotosTabChip);
+        }
+    }
+
+    private static Chip generateTabChip(LayoutInflater inflater, ViewGroup parent, String title) {
+        final Chip chip = (Chip) inflater.inflate(R.layout.picker_chip_tab_header, parent, false);
+        chip.setText(title);
+        return chip;
+    }
+
+    private void initTabChips() {
+        initPhotosTabChip();
+        initAlbumsTabChip();
+    }
+
+    private void initPhotosTabChip() {
+        if (mPhotosTabChip == null) {
+            mPhotosTabChip = generateTabChip(getLayoutInflater(), mTabChipContainer,
+                    getString(R.string.picker_photos));
+            mTabChipContainer.addView(mPhotosTabChip);
+            mPhotosTabChip.setOnClickListener(this::onTabChipClick);
+            mPhotosTabChip.setTag(TAB_CHIP_TYPE_PHOTOS);
+        }
+    }
+
+    private void initAlbumsTabChip() {
+        if (mAlbumsTabChip == null) {
+            mAlbumsTabChip = generateTabChip(getLayoutInflater(), mTabChipContainer,
+                    getString(R.string.picker_albums));
+            mTabChipContainer.addView(mAlbumsTabChip);
+            mAlbumsTabChip.setOnClickListener(this::onTabChipClick);
+            mAlbumsTabChip.setTag(TAB_CHIP_TYPE_ALBUMS);
+        }
+    }
+
+    private void onTabChipClick(@NonNull View view) {
+        final int chipType = (int) view.getTag();
+        mSelectedTabChipType = chipType;
+
+        // Check whether the tabChip is already selected or not. If it is selected, do nothing
+        if (view.isSelected()) {
+            return;
+        }
+
+        if (chipType == TAB_CHIP_TYPE_PHOTOS) {
+            mPhotosTabChip.setSelected(true);
+            mAlbumsTabChip.setSelected(false);
+            PhotosTabFragment.show(getSupportFragmentManager(), Category.getDefaultCategory());
+        } else { // CHIP_TYPE_ALBUMS
+            mPhotosTabChip.setSelected(false);
+            mAlbumsTabChip.setSelected(true);
+            AlbumsTabFragment.show(getSupportFragmentManager());
+        }
+    }
+
     private void setUpWorkProfileToggleSwitch(Switch profileSwitch) {
         if (mUserIdManager.isManagedUserId()) {
             profileSwitch.setChecked(true);
@@ -162,4 +290,20 @@
         setResult(Activity.RESULT_CANCELED);
         finish();
     }
+
+    /**
+     * Update the icons and show/hide the tab chips with {@code shouldShowTabChips}
+     *
+     * @param shouldShowTabChips {@code true}, show the tab chips and show close icon. Otherwise,
+     *                           hide the tab chips and show back icon
+     */
+    public void updateToolbar(boolean shouldShowTabChips) {
+        if (shouldShowTabChips) {
+            getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);
+            mTabChipContainer.setVisibility(View.VISIBLE);
+        } else {
+            getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_arrow_back);
+            mTabChipContainer.setVisibility(View.GONE);
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
index 394b557..8c1fe8a 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
@@ -154,7 +154,7 @@
     /**
      * Create the fragment with the category and add it into the FragmentManager
      *
-     * @param fm       The fragment manager
+     * @param fm the fragment manager
      * @param category the category
      */
     public static void show(FragmentManager fm, Category category) {
diff --git a/src/com/android/providers/media/photopicker/ui/PreviewFragment.java b/src/com/android/providers/media/photopicker/ui/PreviewFragment.java
index 85ca6a3..31f1e42 100644
--- a/src/com/android/providers/media/photopicker/ui/PreviewFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/PreviewFragment.java
@@ -28,7 +28,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.lifecycle.ViewModelProvider;
@@ -59,17 +58,11 @@
     public View onCreateView(LayoutInflater inflater, ViewGroup parent,
             Bundle savedInstanceState) {
         mPickerViewModel = new ViewModelProvider(requireActivity()).get(PickerViewModel.class);
-        // TODO(b/185801129): Add handler for back button to go back to previous fragment/activity
-        // instead of exiting the activity.
         return inflater.inflate(R.layout.fragment_preview, parent, /* attachToRoot */ false);
     }
 
     @Override
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        // Hide the toolbar for now. TODO(185801129): Change the layout of the toolbar or add new
-        // toolbar that can overlap with image/video preview if necessary
-        ((AppCompatActivity)getActivity()).getSupportActionBar().hide();
-
         // Warning: The below code assumes that getSelectedItems will never return null.
         // We are creating a new ArrayList with selected items, this list used as data for the
         // adapter. If activity gets killed and recreated, we will lose items that were deselected.
@@ -136,6 +129,7 @@
         // TODO(185801129): Change the layout of the toolbar or add new toolbar that can overlap
         // with image/video preview if necessary
         getActivity().setTitle("");
+        ((PhotoPickerActivity) getActivity()).updateToolbar(/* showTabChips= */ false);
 
         // This is necessary to ensure we call ViewHolder#bind() onResume()
         if (mAdapter != null) {
@@ -203,7 +197,7 @@
 
     /**
      * Get the fragment in the FragmentManager
-     * @param fm The fragment manager
+     * @param fm the fragment manager
      */
     public static Fragment get(FragmentManager fm) {
         return fm.findFragmentByTag(TAG);