Merge "[PK Setting] add keyboard review under keyboard selection page" into main
diff --git a/res/layout/keyboard_layout_picker.xml b/res/layout/keyboard_layout_picker.xml
index 6b163da..b25c228 100644
--- a/res/layout/keyboard_layout_picker.xml
+++ b/res/layout/keyboard_layout_picker.xml
@@ -20,6 +20,13 @@
     android:id="@+id/keyboard_layout_picker_container"
     android:orientation="vertical">
 
+    <ImageView
+        android:id="@+id/keyboard_layout_preview"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:adjustViewBounds="true"
+        android:scaleType="fitCenter"/>
+
     <FrameLayout
         android:id="@+id/keyboard_layout_title"
         android:layout_width="match_parent"
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index d7a276e..66397c0 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -479,7 +479,10 @@
                 mDialogFragment.dismiss();
                 mDialogFragment = null;
             }
-            getListView().clearOnScrollListeners();
+            RecyclerView view = getListView();
+            if (view != null) {
+                view.clearOnScrollListeners();
+            }
         }
         super.onDetach();
     }
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
index 11740ec..e934964 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
@@ -27,6 +27,20 @@
 public class NewKeyboardLayoutPickerContent extends DashboardFragment {
 
     private static final String TAG = "KeyboardLayoutPicker";
+    private NewKeyboardLayoutPickerController mNewKeyboardLayoutPickerController;
+    private ControllerUpdateCallback mControllerUpdateCallback;
+
+    public interface ControllerUpdateCallback {
+        /**
+         * Called when mNewKeyBoardLayoutPickerController been initialized.
+         */
+        void onControllerUpdated(NewKeyboardLayoutPickerController
+                newKeyboardLayoutPickerController);
+    }
+
+    public void setControllerUpdateCallback(ControllerUpdateCallback controllerUpdateCallback) {
+        this.mControllerUpdateCallback = controllerUpdateCallback;
+    }
 
     @Override
     public void onAttach(Context context) {
@@ -40,7 +54,11 @@
             getActivity().finish();
             return;
         }
-        use(NewKeyboardLayoutPickerController.class).initialize(this);
+        mNewKeyboardLayoutPickerController = use(NewKeyboardLayoutPickerController.class);
+        mNewKeyboardLayoutPickerController.initialize(this);
+        if (mControllerUpdateCallback != null) {
+            mControllerUpdateCallback.onControllerUpdated(mNewKeyboardLayoutPickerController);
+        }
     }
 
     @Override
@@ -56,4 +74,8 @@
     protected int getPreferenceScreenResId() {
         return R.xml.new_keyboard_layout_picker_fragment;
     }
+
+    public NewKeyboardLayoutPickerController getController() {
+        return mNewKeyboardLayoutPickerController;
+    }
 }
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
index 9545276..ac8037f 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
@@ -59,6 +59,7 @@
     private String mFinalSelectedLayout;
     private String mLayout;
     private MetricsFeatureProvider mMetricsFeatureProvider;
+    private KeyboardLayoutSelectedCallback mKeyboardLayoutSelectedCallback;
 
     public NewKeyboardLayoutPickerController(Context context, String key) {
         super(context, key);
@@ -100,7 +101,7 @@
 
     @Override
     public void onStop() {
-        if (!mLayout.equals(mFinalSelectedLayout)) {
+        if (mLayout != null && !mLayout.equals(mFinalSelectedLayout)) {
             String change = "From:" + mLayout + ", to:" + mFinalSelectedLayout;
             mMetricsFeatureProvider.action(
                     mContext, SettingsEnums.ACTION_PK_LAYOUT_CHANGED, change);
@@ -121,6 +122,14 @@
         return AVAILABLE;
     }
 
+    /**
+     * Registers {@link KeyboardLayoutSelectedCallback} and get updated.
+     */
+    public void registerKeyboardSelectedCallback(KeyboardLayoutSelectedCallback
+            keyboardLayoutSelectedCallback) {
+        this.mKeyboardLayoutSelectedCallback = keyboardLayoutSelectedCallback;
+    }
+
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (!(preference instanceof TickButtonPreference)) {
@@ -128,6 +137,9 @@
         }
 
         final TickButtonPreference pref = (TickButtonPreference) preference;
+        if (mKeyboardLayoutSelectedCallback != null && mPreferenceMap.containsKey(preference)) {
+            mKeyboardLayoutSelectedCallback.onSelected(mPreferenceMap.get(preference));
+        }
         pref.setSelected(true);
         if (mPreviousSelection != null && !mPreviousSelection.equals(preference.getKey())) {
             TickButtonPreference preSelectedPref = mScreen.findPreference(mPreviousSelection);
@@ -166,6 +178,9 @@
             pref.setTitle(layout.getLabel());
 
             if (mLayout.equals(layout.getLabel())) {
+                if (mKeyboardLayoutSelectedCallback != null) {
+                    mKeyboardLayoutSelectedCallback.onSelected(layout);
+                }
                 pref.setSelected(true);
                 mPreviousSelection = layout.getDescriptor();
             }
@@ -200,4 +215,11 @@
         }
         return label;
     }
+
+    public interface KeyboardLayoutSelectedCallback {
+        /**
+         * Called when KeyboardLayout been selected.
+         */
+        void onSelected(KeyboardLayout keyboardLayout);
+    }
 }
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java
index 88cacd2..f583971 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java
@@ -16,35 +16,75 @@
 
 package com.android.settings.inputmethod;
 
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import android.graphics.drawable.Drawable;
+import android.hardware.input.InputManager;
+import android.hardware.input.KeyboardLayout;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ImageView;
 
 import androidx.fragment.app.Fragment;
 
 import com.android.settings.R;
 
+//TODO: b/316243168 - [Physical Keyboard Setting] Refactor NewKeyboardLayoutPickerFragment
 public class NewKeyboardLayoutPickerFragment extends Fragment {
+    private static final int DEFAULT_KEYBOARD_PREVIEW_WIDTH = 1630;
+    private static final int DEFAULT_KEYBOARD_PREVIEW_HEIGHT = 540;
+
+    private ImageView mKeyboardLayoutPreview;
+    private InputManager mInputManager;
+    private final NewKeyboardLayoutPickerController.KeyboardLayoutSelectedCallback
+            mKeyboardLayoutSelectedCallback =
+            new NewKeyboardLayoutPickerController.KeyboardLayoutSelectedCallback() {
+                @Override
+                public void onSelected(KeyboardLayout keyboardLayout) {
+                    if (mInputManager != null && mKeyboardLayoutPreview != null) {
+                        Drawable previewDrawable = mInputManager.getKeyboardLayoutPreview(
+                                keyboardLayout,
+                                DEFAULT_KEYBOARD_PREVIEW_WIDTH, DEFAULT_KEYBOARD_PREVIEW_HEIGHT);
+                        mKeyboardLayoutPreview.setVisibility(
+                                previewDrawable == null ? GONE : VISIBLE);
+                        if (previewDrawable != null) {
+                            mKeyboardLayoutPreview.setImageDrawable(previewDrawable);
+                        }
+                    }
+                }
+            };
+
+    private final NewKeyboardLayoutPickerContent.ControllerUpdateCallback
+            mControllerUpdateCallback =
+                    newKeyboardLayoutPickerController -> {
+                        if (newKeyboardLayoutPickerController != null) {
+                            newKeyboardLayoutPickerController.registerKeyboardSelectedCallback(
+                                    mKeyboardLayoutSelectedCallback);
+                        }
+                    };
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
-
+        mInputManager = requireContext().getSystemService(InputManager.class);
         ViewGroup fragmentView = (ViewGroup) inflater.inflate(
                 R.layout.keyboard_layout_picker, container, false);
+        mKeyboardLayoutPreview = fragmentView.findViewById(R.id.keyboard_layout_preview);
         getActivity().getSupportFragmentManager()
                 .beginTransaction()
                 .replace(R.id.keyboard_layout_title, new NewKeyboardLayoutPickerTitle())
                 .commit();
 
         NewKeyboardLayoutPickerContent fragment = new NewKeyboardLayoutPickerContent();
+        fragment.setControllerUpdateCallback(mControllerUpdateCallback);
         fragment.setArguments(getArguments());
         getActivity().getSupportFragmentManager()
                 .beginTransaction()
                 .replace(R.id.keyboard_layouts, fragment)
                 .commit();
-
         return fragmentView;
     }
 }