Fix abnormal ripple effect of bottom tab

Root cause: ThemeFragment and GridFragment are updating the bottom action bar visibility from Visible to Gone quickly, the visiblity change of bottom action bar also update the visiblity of bottom nav. So we will see the ripple effect being abnormal.

Solution:
1. Restrict BottomNav to update visibility, not every time.
2. Make sure ThemeFragment and GridFragment didn't update visibility of BottomActionBar several times when initializing.

Video: https://drive.google.com/file/d/1p5cSPnZ6kHXDeXiTZIavJ_mOKMu7wAtY/view?usp=sharing

Test: Manually
Fixes: 159685933
Change-Id: Ia61d7af21c143c9da5e441cbcef34c0397cb3181
diff --git a/src/com/android/customization/picker/CustomizationPickerActivity.java b/src/com/android/customization/picker/CustomizationPickerActivity.java
index 2ee114b..0ce8ac1 100644
--- a/src/com/android/customization/picker/CustomizationPickerActivity.java
+++ b/src/com/android/customization/picker/CustomizationPickerActivity.java
@@ -126,10 +126,19 @@
 
         setContentView(R.layout.activity_customization_picker_main);
         setUpBottomNavView();
+        mBottomActionBar = findViewById(R.id.bottom_actionbar);
+        mBottomActionBar.addVisibilityChangeListener(
+                isBottomActionBarVisible -> {
+                    boolean isBottomNavVisible = mBottomNav.getVisibility() == View.VISIBLE;
+                    // Switch the visibility of BottomNav if visibility of BottomActionBar and
+                    // BottomNav are same.
+                    if (isBottomActionBarVisible == isBottomNavVisible) {
+                        mBottomNav.setVisibility(isBottomActionBarVisible
+                                ? View.GONE : View.VISIBLE);
+                    }
+                });
 
-        FragmentManager fm = getSupportFragmentManager();
-        Fragment fragment = fm.findFragmentById(R.id.fragment_container);
-
+        Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
         if (fragment == null) {
             // App launch specific logic: log the "app launched" event and set up daily logging.
             mUserEventLogger.logAppLaunched();
@@ -143,10 +152,6 @@
                     WALLPAPER_FOCUS.equals(getIntent().getStringExtra(WALLPAPER_FLAVOR_EXTRA))
                             ? R.id.nav_wallpaper : R.id.nav_theme);
         }
-
-        mBottomActionBar = findViewById(R.id.bottom_actionbar);
-        mBottomActionBar.addVisibilityChangeListener(
-                isVisible -> mBottomNav.setVisibility(isVisible ? View.GONE : View.VISIBLE));
     }
 
     @Override
diff --git a/src/com/android/customization/picker/grid/GridFragment.java b/src/com/android/customization/picker/grid/GridFragment.java
index dbce456..98c7515 100644
--- a/src/com/android/customization/picker/grid/GridFragment.java
+++ b/src/com/android/customization/picker/grid/GridFragment.java
@@ -39,6 +39,7 @@
 
 import com.android.customization.model.CustomizationManager.Callback;
 import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
+import com.android.customization.model.CustomizationOption;
 import com.android.customization.model.grid.GridOption;
 import com.android.customization.model.grid.GridOptionsManager;
 import com.android.customization.module.ThemesUserEventLogger;
@@ -63,8 +64,8 @@
 
     private static final int FULL_PREVIEW_REQUEST_CODE = 1000;
     private static final String KEY_STATE_SELECTED_OPTION = "GridFragment.selectedOption";
-    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY =
-            "GridFragment.bottomActionBarVisibility";
+    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE =
+            "GridFragment.bottomActionBarVisible";
 
     private static final String TAG = "GridFragment";
 
@@ -177,8 +178,7 @@
             outState.putParcelable(KEY_STATE_SELECTED_OPTION, mSelectedOption);
         }
         if (mBottomActionBar != null) {
-            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY,
-                    mBottomActionBar.isVisible());
+            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE, mBottomActionBar.isVisible());
         }
     }
 
@@ -211,14 +211,9 @@
             public void onOptionsLoaded(List<GridOption> options) {
                 mLoading.hide();
                 mOptionsController = new OptionSelectorController<>(mOptionsContainer, options);
-                mOptionsController.addListener(selected -> {
-                    mSelectedOption = (GridOption) selected;
-                    mBottomActionBar.show();
-                    mEventLogger.logGridSelected(mSelectedOption);
-                    mGridOptionPreviewer.setGridOption(mSelectedOption);
-                });
                 mOptionsController.initOptions(mGridManager);
 
+                // Find the selected Grid option.
                 GridOption previouslySelectedOption = null;
                 if (savedInstanceState != null) {
                     previouslySelectedOption = findEquivalent(
@@ -227,15 +222,15 @@
                 mSelectedOption = previouslySelectedOption != null
                         ? previouslySelectedOption
                         : getActiveOption(options);
-                // Will trigger selected listener.
+
                 mOptionsController.setSelectedOption(mSelectedOption);
-                boolean bottomActionBarVisibility = savedInstanceState != null
-                        && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY);
-                if (bottomActionBarVisibility) {
+                onOptionSelected(mSelectedOption);
+                restoreBottomActionBarVisibility(savedInstanceState);
+
+                mOptionsController.addListener(selectedOption -> {
+                    onOptionSelected(selectedOption);
                     mBottomActionBar.show();
-                } else {
-                    mBottomActionBar.hide();
-                }
+                });
             }
 
             @Override
@@ -275,6 +270,22 @@
         mError.setVisibility(View.VISIBLE);
     }
 
+    private void onOptionSelected(CustomizationOption selectedOption) {
+        mSelectedOption = (GridOption) selectedOption;
+        mEventLogger.logGridSelected(mSelectedOption);
+        mGridOptionPreviewer.setGridOption(mSelectedOption);
+    }
+
+    private void restoreBottomActionBarVisibility(@Nullable Bundle savedInstanceState) {
+        boolean isBottomActionBarVisible = savedInstanceState != null
+                && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE);
+        if (isBottomActionBarVisible) {
+            mBottomActionBar.show();
+        } else {
+            mBottomActionBar.hide();
+        }
+    }
+
     private void showFullPreview() {
         Bundle bundle = new Bundle();
         bundle.putParcelable(EXTRA_WALLPAPER_INFO, mHomeWallpaper);
diff --git a/src/com/android/customization/picker/theme/ThemeFragment.java b/src/com/android/customization/picker/theme/ThemeFragment.java
index 077b733..4b77214 100644
--- a/src/com/android/customization/picker/theme/ThemeFragment.java
+++ b/src/com/android/customization/picker/theme/ThemeFragment.java
@@ -43,6 +43,7 @@
 
 import com.android.customization.model.CustomizationManager.Callback;
 import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
+import com.android.customization.model.CustomizationOption;
 import com.android.customization.model.theme.ThemeBundle;
 import com.android.customization.model.theme.ThemeManager;
 import com.android.customization.model.theme.custom.CustomTheme;
@@ -68,8 +69,8 @@
 
     private static final String TAG = "ThemeFragment";
     private static final String KEY_SELECTED_THEME = "ThemeFragment.SelectedThemeBundle";
-    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY =
-            "ThemeFragment.bottomActionBarVisibility";
+    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE =
+            "ThemeFragment.bottomActionBarVisible";
     private static final int FULL_PREVIEW_REQUEST_CODE = 1000;
 
     /**
@@ -221,8 +222,7 @@
             outState.putString(KEY_SELECTED_THEME, mSelectedTheme.getSerializedPackages());
         }
         if (mBottomActionBar != null) {
-            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY,
-                    mBottomActionBar.isVisible());
+            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE, mBottomActionBar.isVisible());
         }
     }
 
@@ -275,30 +275,10 @@
             @Override
             public void onOptionsLoaded(List<ThemeBundle> options) {
                 mOptionsController = new OptionSelectorController<>(mOptionsContainer, options);
-                mOptionsController.addListener(selected -> {
-                    mLoading.hide();
-                    if (selected instanceof CustomTheme && !((CustomTheme) selected).isDefined()) {
-                        navigateToCustomTheme((CustomTheme) selected);
-                    } else {
-                        mSelectedTheme = (ThemeBundle) selected;
-                        mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
-                        mEventLogger.logThemeSelected(mSelectedTheme,
-                                selected instanceof CustomTheme);
-                        mThemeOptionPreviewer.setPreviewInfo(mSelectedTheme.getPreviewInfo());
-                        if (mThemeInfoView != null && mSelectedTheme != null) {
-                            mThemeInfoView.populateThemeInfo(mSelectedTheme);
-                        }
-
-                        if (selected instanceof CustomTheme) {
-                            mBottomActionBar.showActionsOnly(INFORMATION, CUSTOMIZE, APPLY);
-                        } else {
-                            mBottomActionBar.showActionsOnly(INFORMATION, APPLY);
-                        }
-                        mBottomActionBar.show();
-                    }
-                });
                 mOptionsController.initOptions(mThemeManager);
 
+                // Find out the selected theme option.
+                // 1. Find previously selected theme.
                 String previouslySelected = savedInstanceState != null
                         ? savedInstanceState.getString(KEY_SELECTED_THEME) : null;
                 ThemeBundle previouslySelectedTheme = null;
@@ -312,22 +292,26 @@
                         activeTheme = theme;
                     }
                 }
+                // 2. Use active theme if no previously selected theme.
                 mSelectedTheme = previouslySelectedTheme != null
                         ? previouslySelectedTheme
                         : activeTheme;
-
+                // 3. Select the default theme if there is no matching custom enabled theme.
                 if (mSelectedTheme == null) {
-                    // Select the default theme if there is no matching custom enabled theme
                     mSelectedTheme = findDefaultThemeBundle(options);
                 }
+
                 mOptionsController.setSelectedOption(mSelectedTheme);
-                boolean bottomActionBarVisibility = savedInstanceState != null
-                        && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY);
-                if (bottomActionBarVisibility) {
-                    mBottomActionBar.show();
-                } else {
-                    mBottomActionBar.hide();
-                }
+                onOptionSelected(mSelectedTheme);
+                restoreBottomActionBarVisibility(savedInstanceState);
+
+                mOptionsController.addListener(selectedOption -> {
+                    onOptionSelected(selectedOption);
+                    if (!isAddCustomThemeOption(selectedOption)) {
+                        mBottomActionBar.show();
+                    }
+                });
+                mLoading.hide();
             }
             @Override
             public void onError(@Nullable Throwable throwable) {
@@ -370,6 +354,41 @@
         return null;
     }
 
+    private void onOptionSelected(CustomizationOption selectedOption) {
+        if (isAddCustomThemeOption(selectedOption)) {
+            navigateToCustomTheme((CustomTheme) selectedOption);
+        } else {
+            mSelectedTheme = (ThemeBundle) selectedOption;
+            mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
+            mEventLogger.logThemeSelected(mSelectedTheme,
+                    selectedOption instanceof CustomTheme);
+            mThemeOptionPreviewer.setPreviewInfo(mSelectedTheme.getPreviewInfo());
+            if (mThemeInfoView != null && mSelectedTheme != null) {
+                mThemeInfoView.populateThemeInfo(mSelectedTheme);
+            }
+
+            if (selectedOption instanceof CustomTheme) {
+                mBottomActionBar.showActionsOnly(INFORMATION, CUSTOMIZE, APPLY);
+            } else {
+                mBottomActionBar.showActionsOnly(INFORMATION, APPLY);
+            }
+        }
+    }
+
+    private void restoreBottomActionBarVisibility(@Nullable Bundle savedInstanceState) {
+        boolean isBottomActionBarVisible = savedInstanceState != null
+                && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE);
+        if (isBottomActionBarVisible) {
+            mBottomActionBar.show();
+        } else {
+            mBottomActionBar.hide();
+        }
+    }
+
+    private boolean isAddCustomThemeOption(CustomizationOption option) {
+        return option instanceof CustomTheme && !((CustomTheme) option).isDefined();
+    }
+
     private void navigateToCustomTheme(CustomTheme themeToEdit) {
         Intent intent = new Intent(getActivity(), CustomThemeActivity.class);
         intent.putExtra(CustomThemeActivity.EXTRA_THEME_TITLE, themeToEdit.getTitle());