Implement new grid applying experience

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

Without mReloadOptionsAfterApplying flag, reload preview would fail when applied grid, and had a performance problem, the simplest way is to add the flag to prevent it reload when applying.
Video without mReloadOptionsAfterApplying flag: https://drive.google.com/a/google.com/file/d/1XFpydX9YFj_IjfOutyXBBnzImmRCaIKS/view?usp=sharing

New applied string are confirmed in b/151289552

Test: Manually
Bug: 151289552
Change-Id: I3f39d80c66940cc1cf2db687294f67924cc8a3c3
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7155119..c0aef7a 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -99,10 +99,13 @@
     <string name="grid_title_pattern"><xliff:g name="num_cols" example="1">%1$d</xliff:g>x<xliff:g name="num_rows" example="1">%2$d</xliff:g></string>
 
     <!-- Message shown when a theme has been applied successfully in the system [CHAR LIMIT=NONE] -->
-    <string name="applied_theme_msg">Style applied</string>
+    <string name="applied_theme_msg">Style set successfully</string>
 
     <!-- Message shown when a clock has been applied successfully in the system [CHAR LIMIT=NONE] -->
-    <string name="applied_clock_msg">Clock applied</string>
+    <string name="applied_clock_msg">Clock set successfully</string>
+
+    <!-- Message shown when a grid has been applied successfully in the system [CHAR LIMIT=NONE] -->
+    <string name="applied_grid_msg">Grid set successfully</string>
 
     <!-- Message shown when a theme couldn't be applied in the system because of an error
         [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/customization/model/grid/GridOptionsManager.java b/src/com/android/customization/model/grid/GridOptionsManager.java
index b0e0787..84f5373 100644
--- a/src/com/android/customization/model/grid/GridOptionsManager.java
+++ b/src/com/android/customization/model/grid/GridOptionsManager.java
@@ -58,7 +58,7 @@
 
     @Override
     public void fetchOptions(OptionsFetchedListener<GridOption> callback, boolean reload) {
-        new FetchTask(mProvider, callback).execute();
+        new FetchTask(mProvider, callback, reload).execute();
     }
 
     /** See if using surface view to render grid options */
@@ -74,16 +74,18 @@
     private static class FetchTask extends AsyncTask<Void, Void, Pair<List<GridOption>, String>> {
         private final LauncherGridOptionsProvider mProvider;
         @Nullable private final OptionsFetchedListener<GridOption> mCallback;
+        private final boolean mReload;
 
         private FetchTask(@NonNull LauncherGridOptionsProvider provider,
-                @Nullable OptionsFetchedListener<GridOption> callback) {
+                @Nullable OptionsFetchedListener<GridOption> callback, boolean reload) {
             mCallback = callback;
             mProvider = provider;
+            mReload = reload;
         }
 
         @Override
         protected Pair<List<GridOption>, String> doInBackground(Void[] params) {
-            return mProvider.fetch(false);
+            return mProvider.fetch(mReload);
         }
 
         @Override
diff --git a/src/com/android/customization/picker/grid/GridFragment.java b/src/com/android/customization/picker/grid/GridFragment.java
index 6e63a10..1a26755 100644
--- a/src/com/android/customization/picker/grid/GridFragment.java
+++ b/src/com/android/customization/picker/grid/GridFragment.java
@@ -37,6 +37,7 @@
 import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
 import android.widget.ImageView;
+import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -106,6 +107,41 @@
     private View mError;
     private BottomActionBar mBottomActionBar;
     private ThemesUserEventLogger mEventLogger;
+    private boolean mReloadOptionsAfterApplying;
+
+    private final Callback mApplyGridCallback = new Callback() {
+        @Override
+        public void onSuccess() {
+            mGridManager.fetchOptions(new OptionsFetchedListener<GridOption>() {
+                @Override
+                public void onOptionsLoaded(List<GridOption> options) {
+                    mOptionsController.resetOptions(options);
+                    mSelectedOption = getSelectedOption(options);
+                    mReloadOptionsAfterApplying = true;
+                    // It will trigger OptionSelectedListener#onOptionSelected.
+                    mOptionsController.setSelectedOption(mSelectedOption);
+                    Toast.makeText(getContext(), R.string.applied_grid_msg, Toast.LENGTH_SHORT)
+                            .show();
+                    // Since we disabled it when clicked apply button.
+                    mBottomActionBar.enableActions();
+                    mBottomActionBar.hide();
+                }
+
+                @Override
+                public void onError(@Nullable Throwable throwable) {
+                    if (throwable != null) {
+                        Log.e(TAG, "Error loading grid options", throwable);
+                    }
+                    showError();
+                }
+            }, true);
+        }
+
+        @Override
+        public void onError(@Nullable Throwable throwable) {
+            //TODO(chihhangchuang): handle
+        }
+    };
 
     @Override
     public void onAttach(Context context) {
@@ -176,17 +212,7 @@
         mBottomActionBar.setActionClickListener(CANCEL, unused -> getActivity().onBackPressed());
         mBottomActionBar.setActionClickListener(APPLY, unused -> {
             mBottomActionBar.disableActions();
-            mGridManager.apply(mSelectedOption, new Callback() {
-                @Override
-                public void onSuccess() {
-                    getActivity().finish();
-                }
-
-                @Override
-                public void onError(@Nullable Throwable throwable) {
-                    //TODO(santie): handle
-                }
-            });
+            mGridManager.apply(mSelectedOption, mApplyGridCallback);
         });
     }
 
@@ -220,20 +246,16 @@
 
                 mOptionsController.addListener(selected -> {
                     mSelectedOption = (GridOption) selected;
+                    if (mReloadOptionsAfterApplying) {
+                        mReloadOptionsAfterApplying = false;
+                        return;
+                    }
                     mBottomActionBar.show();
                     mEventLogger.logGridSelected(mSelectedOption);
                     createAdapter();
                 });
                 mOptionsController.initOptions(mGridManager);
-                for (GridOption option : options) {
-                    if (option.isActive(mGridManager)) {
-                        mSelectedOption = option;
-                    }
-                }
-                // For development only, as there should always be a grid set.
-                if (mSelectedOption == null) {
-                    mSelectedOption = options.get(0);
-                }
+                mSelectedOption = getSelectedOption(options);
                 createAdapter();
             }
 
@@ -247,6 +269,14 @@
         }, false);
     }
 
+    private GridOption getSelectedOption(List<GridOption> options) {
+        return options.stream()
+                .filter(option -> option.isActive(mGridManager))
+                .findAny()
+                // For development only, as there should always be a grid set.
+                .orElse(options.get(0));
+    }
+
     private void hideError() {
         mContent.setVisibility(View.VISIBLE);
         mError.setVisibility(View.GONE);