Add surface view to IME

Applications that choose to hide the content area and draw their own view will use this surface area to draw on.

Fix: 171056783
Bug: 162268101
Bug: 170343703
Test: Manual
Change-Id: Ia6899bbe54773ae3752131dd662508bfe69c9a0e
Merged-In: Ia6899bbe54773ae3752131dd662508bfe69c9a0e
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java
index 07c3347..11d33f4 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java
@@ -102,8 +102,8 @@
         onView(withId(R.id.car_ui_wideScreenSearchResultList)).check(matches(not(isDisplayed())));
         onView(withId(R.id.car_ui_wideScreenErrorMessage)).check(matches(not(isDisplayed())));
         onView(withId(R.id.car_ui_wideScreenError)).check(matches(not(isDisplayed())));
+        onView(withId(R.id.car_ui_contentAreaAutomotive)).check(matches(not(isDisplayed())));
 
-        onView(withId(R.id.car_ui_contentAreaAutomotive)).check(matches(isDisplayed()));
         onView(withId(R.id.car_ui_wideScreenExtractedTextIcon)).check(matches(isDisplayed()));
         onView(withId(R.id.car_ui_wideScreenClearData)).check(matches(isDisplayed()));
         onView(withId(R.id.car_ui_fullscreenArea)).check(matches(isDisplayed()));
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java
index 98fddc7..953cf4d 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java
@@ -23,11 +23,16 @@
 import android.graphics.drawable.Drawable;
 import android.inputmethodservice.ExtractEditText;
 import android.inputmethodservice.InputMethodService;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Gravity;
+import android.view.SurfaceControlViewHost.SurfacePackage;
+import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
@@ -64,9 +69,9 @@
  *      <li>return {@link #onEvaluateFullscreenMode(boolean)} from
  *      {@link InputMethodService#onEvaluateFullscreenMode()}</li>
  *      <li>return the view created by
- *      {@link #createWideScreenImeView(View, Context, InputMethodService)}
+ *      {@link #createWideScreenImeView(View)}
  *      from {@link InputMethodService#onCreateInputView()}</li>
- *      <li>{@link #onComputeInsets(InputMethodService.Insets, View)} should be called from
+ *      <li>{@link #onComputeInsets(InputMethodService.Insets) should be called from
  *      {@link InputMethodService#onComputeInsets(InputMethodService.Insets)}</li>
  *      <li>{@link #onAppPrivateCommand(String, Bundle) should be called from {
  *      @link InputMethodService#onAppPrivateCommand(String, Bundle)}}</li>
@@ -144,9 +149,20 @@
     // ArrayList<Integer>
     public static final String SEARCH_RESULT_SECONDARY_IMAGE_RES_ID_LIST =
             "search_result_image_list";
+    // key used to provide the surface package information by the application to the IME. IME
+    // will send the surface info each time its being displayed.
+    public static final String CONTENT_AREA_SURFACE_PACKAGE = "content_area_surface_package";
+    // key to provide the host token of surface view by IME to the application.
+    public static final String CONTENT_AREA_SURFACE_HOST_TOKEN = "content_area_surface_host_token";
+    // key to provide the display id of surface view by IME to the application.
+    public static final String CONTENT_AREA_SURFACE_DISPLAY_ID = "content_area_surface_display_id";
+    // key to provide the height of surface view by IME to the application.
+    public static final String CONTENT_AREA_SURFACE_HEIGHT = "content_area_surface_height";
+    // key to provide the width of surface view by IME to the application.
+    public static final String CONTENT_AREA_SURFACE_WIDTH = "content_area_surface_width";
 
     private View mRootView;
-    private Context mContext;
+    private final Context mContext;
     @Nullable
     private View mExtractActionAutomotive;
     @NonNull
@@ -154,7 +170,8 @@
     // whether to render the content area for automotive when in wide screen mode.
     private boolean mImeRendersAllContent = true;
     private boolean mAllowAppToHideContentArea;
-    private ArrayList<CarUiListItem> mAutomotiveSearchItems = new ArrayList<>();
+    @Nullable
+    private ArrayList<CarUiListItem> mAutomotiveSearchItems;
     @NonNull
     private TextView mWideScreenDescriptionTitle;
     @NonNull
@@ -180,8 +197,10 @@
     @NonNull
     private View mFullscreenArea;
     @NonNull
+    private SurfaceView mContentAreaSurfaceView;
+    @NonNull
     private FrameLayout mInputExtractEditTextContainer;
-    private InputMethodService mInputMethodService;
+    private final InputMethodService mInputMethodService;
 
     public CarUiImeWideScreenController(@NonNull Context context, @NonNull InputMethodService ims) {
         mContext = context;
@@ -209,6 +228,8 @@
                 mContext.getResources().getBoolean(
                         R.bool.car_ui_ime_wide_screen_allow_app_hide_content_area);
 
+        mContentAreaSurfaceView = mRootView.requireViewById(R.id.car_ui_ime_surface);
+        mContentAreaSurfaceView.setZOrderOnTop(true);
         mWideScreenDescriptionTitle =
                 mRootView.requireViewById(R.id.car_ui_wideScreenDescriptionTitle);
         mWideScreenDescription = mRootView.requireViewById(R.id.car_ui_wideScreenDescription);
@@ -281,15 +302,27 @@
      * @param data   Any data to include with the command.
      */
     public void onAppPrivateCommand(String action, Bundle data) {
-        if (!isWideScreenMode() || data == null || !WIDE_SCREEN_ACTION.equals(action)) {
+        if (!isWideScreenMode() || !WIDE_SCREEN_ACTION.equals(action)) {
             return;
         }
         resetAutomotiveWideScreenViews();
+        if (data == null) {
+            return;
+        }
         if (mAllowAppToHideContentArea || (mInputEditorInfo != null && allowPackageList().contains(
                 mInputEditorInfo.packageName))) {
             mImeRendersAllContent = data.getBoolean(REQUEST_RENDER_CONTENT_AREA, true);
         }
 
+        if (data.getParcelable(CONTENT_AREA_SURFACE_PACKAGE) != null
+                && Build.VERSION.SDK_INT >= VERSION_CODES.R) {
+            SurfacePackage surfacePackage = (SurfacePackage) data.getParcelable(
+                    CONTENT_AREA_SURFACE_PACKAGE);
+            mContentAreaSurfaceView.setChildSurfacePackage(surfacePackage);
+            mContentAreaSurfaceView.setVisibility(View.VISIBLE);
+            mContentAreaAutomotive.setVisibility(View.GONE);
+        }
+
         String discTitle = data.getString(ADD_DESC_TITLE_TO_CONTENT_AREA);
         if (!TextUtils.isEmpty(discTitle)) {
             mWideScreenDescriptionTitle.setText(discTitle);
@@ -337,7 +370,7 @@
         if (mExtractActionAutomotive != null) {
             mExtractActionAutomotive.setVisibility(View.VISIBLE);
         }
-        if (!mAutomotiveSearchItems.isEmpty()) {
+        if (mAutomotiveSearchItems != null) {
             mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
             mRecyclerView.setVerticalScrollBarEnabled(true);
             mRecyclerView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT);
@@ -352,7 +385,6 @@
     }
 
     private void loadSearchItems(Bundle data) {
-        mAutomotiveSearchItems = new ArrayList<>();
         ArrayList<String> itemIdList = data.getStringArrayList(SEARCH_RESULT_ITEM_ID);
         ArrayList<String> titleList = data.getStringArrayList(SEARCH_RESULT_TITLE_LIST);
         ArrayList<String> subTitleList = data.getStringArrayList(SEARCH_RESULT_SUB_TITLE_LIST);
@@ -365,6 +397,7 @@
         if (itemIdList == null) {
             return;
         }
+        mAutomotiveSearchItems = new ArrayList<>();
         for (int i = 0; i < itemIdList.size(); i++) {
             int index = i;
             CarUiImeSearchListItem searchItem;
@@ -494,6 +527,40 @@
         if (hasLabel) {
             intiExtractAction(textForImeAction);
         }
+
+        sendSurfaceInfo();
+    }
+
+    /**
+     * Sends the information for surface view to the application on which they can draw on. This
+     * information will ONLY be sent if OEM allows an application to hide the content area and let
+     * it draw its own content.
+     */
+    private void sendSurfaceInfo() {
+        if (!mAllowAppToHideContentArea && !(mInputEditorInfo != null
+                && allowPackageList().contains(mInputEditorInfo.packageName))) {
+            return;
+        }
+        int displayId = mContentAreaSurfaceView.getDisplay().getDisplayId();
+        IBinder hostToken = mContentAreaSurfaceView.getHostToken();
+
+        Bundle bundle = new Bundle();
+        bundle.putBinder(CONTENT_AREA_SURFACE_HOST_TOKEN, hostToken);
+        bundle.putInt(CONTENT_AREA_SURFACE_DISPLAY_ID, displayId);
+        bundle.putInt(CONTENT_AREA_SURFACE_HEIGHT,
+                mContentAreaSurfaceView.getHeight() + getNavBarHeight());
+        bundle.putInt(CONTENT_AREA_SURFACE_WIDTH, mContentAreaSurfaceView.getWidth());
+
+        mInputConnection.performPrivateCommand(WIDE_SCREEN_ACTION, bundle);
+    }
+
+    private int getNavBarHeight() {
+        Resources resources = mContext.getResources();
+        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
+        if (resourceId > 0) {
+            return resources.getDimensionPixelSize(resourceId);
+        }
+        return 0;
     }
 
     /**
@@ -560,8 +627,8 @@
     }
 
     private List<String> allowPackageList() {
-        String value = mContext.getString(R.string.car_ui_ime_wide_screen_allowed_package_list);
-        String[] packages = value.split(",");
+        String[] packages = mContext.getResources()
+                .getStringArray(R.array.car_ui_ime_wide_screen_allowed_package_list);
         return Arrays.asList(packages);
     }
 
@@ -617,6 +684,7 @@
 
     private void resetAutomotiveWideScreenViews() {
         mWideScreenDescriptionTitle.setVisibility(View.GONE);
+        mContentAreaSurfaceView.setVisibility(View.GONE);
         mWideScreenErrorMessage.setVisibility(View.GONE);
         mRecyclerView.setVisibility(View.GONE);
         mWideScreenDescription.setVisibility(View.GONE);
@@ -629,6 +697,7 @@
         if (mExtractActionAutomotive != null) {
             mExtractActionAutomotive.setVisibility(View.GONE);
         }
+        mContentAreaAutomotive.setVisibility(View.VISIBLE);
         mContentAreaAutomotive.setBackground(
                 mContext.getDrawable(R.drawable.car_ui_ime_wide_screen_no_content_background));
         setExtractedEditTextBackground(R.drawable.car_ui_ime_wide_screen_input_area_tint_color);
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java
index faedd7e..ab85ac8 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java
@@ -16,12 +16,17 @@
 
 package com.android.car.ui.toolbar;
 
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_DISPLAY_ID;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_HEIGHT;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_HOST_TOKEN;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_WIDTH;
 import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_ITEM_ID;
 import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SECONDARY_IMAGE_ID;
 import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_CLEAR_DATA_ACTION;
 
 import android.content.Context;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.util.AttributeSet;
 import android.widget.EditText;
 
@@ -33,28 +38,6 @@
  * allow car-ui-lib to receive responses (like onClick events) from the IMS
  */
 class CarUiEditText extends EditText {
-    /**
-     * Interface for {@link CarUiEditText} to support different actions and callbacks from IME
-     * when running in wide screen mode.
-     */
-    interface PrivateImeCommandCallback {
-        /**
-         * Called when user clicks on an item in the search results.
-         *
-         * @param itemId the id of the item clicked. This will be the same id that was passed by the
-         *               application to the IMS template to display search results.
-         */
-        void onItemClicked(String itemId);
-
-        /**
-         * Called when user clicks on a secondary image within item in the search results.
-         *
-         * @param secondaryImageId the id of the secondary image clicked. This will be the same id
-         *                         that was passed by the application to the IMS template to display
-         *                         search results.
-         */
-        void onSecondaryImageClicked(String secondaryImageId);
-    }
 
     private final Set<PrivateImeCommandCallback> mPrivateImeCommandCallback = new HashSet<>();
 
@@ -104,6 +87,17 @@
             }
         }
 
+        int displayId = data.getInt(CONTENT_AREA_SURFACE_DISPLAY_ID);
+        int height = data.getInt(CONTENT_AREA_SURFACE_HEIGHT);
+        int width = data.getInt(CONTENT_AREA_SURFACE_WIDTH);
+        IBinder binder = data.getBinder(CONTENT_AREA_SURFACE_HOST_TOKEN);
+
+        if (binder != null) {
+            for (PrivateImeCommandCallback listener : mPrivateImeCommandCallback) {
+                listener.onSurfaceInfo(displayId, binder, height, width);
+            }
+        }
+
         return false;
     }
 
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/PrivateImeCommandCallback.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/PrivateImeCommandCallback.java
new file mode 100644
index 0000000..49e7fa4
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/PrivateImeCommandCallback.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package com.android.car.ui.toolbar;
+
+import android.os.IBinder;
+
+/**
+ * Interface for {@link CarUiEditText} to support different actions and callbacks from IME
+ * when running in wide screen mode.
+ */
+public interface PrivateImeCommandCallback {
+    /**
+     * Called when user clicks on an item in the search results.
+     *
+     * @param itemId the id of the item clicked. This will be the same id that was passed by the
+     *               application to the IMS template to display search results.
+     */
+    void onItemClicked(String itemId);
+
+    /**
+     * Called when user clicks on a secondary image within item in the search results.
+     *
+     * @param secondaryImageId the id of the secondary image clicked. This will be the same id
+     *                         that was passed by the application to the IMS template to display
+     *                         search results.
+     */
+    void onSecondaryImageClicked(String secondaryImageId);
+
+    /**
+     * Called when the edit text is clicked and IME is about to launch. IME provides the surface
+     * view information through this call that applications can use to display a view on the
+     * IME surface.
+     *
+     * This method will NOT be called if an OEM has not allowed an application to hide the
+     * content area.
+     */
+    void onSurfaceInfo(int displayId, IBinder binder, int height, int width);
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchView.java
index 55a044d..7b0fe0a 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchView.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchView.java
@@ -17,6 +17,7 @@
 
 import static android.view.WindowInsets.Type.ime;
 
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_PACKAGE;
 import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_ITEM_ID;
 import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_PRIMARY_IMAGE_RES_ID_LIST;
 import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SECONDARY_IMAGE_ID;
@@ -28,14 +29,21 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
 import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
+import android.view.Display;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.SurfaceControlViewHost;
 import android.view.View;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
@@ -43,6 +51,7 @@
 import android.widget.ImageView;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.constraintlayout.widget.ConstraintLayout;
 
 import com.android.car.ui.R;
@@ -68,7 +77,14 @@
     private final int mStartPaddingWithoutIcon;
     private final int mStartPadding;
     private final int mEndPadding;
-    private List<? extends CarUiImeSearchListItem> mWideScreenSearchItemList = new ArrayList<>();
+    @Nullable
+    private View mWideScreenImeContentAreaView;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    private SurfaceControlViewHost mSurfaceControlViewHost;
+    private int mSurfaceHeight;
+    private int mSurfaceWidth;
+    private List<? extends CarUiImeSearchListItem> mWideScreenSearchItemList;
     private final Map<String, CarUiImeSearchListItem> mIdToListItem = new HashMap<>();
 
     private Set<Toolbar.OnSearchListener> mSearchListeners = Collections.emptySet();
@@ -152,31 +168,7 @@
 
         if (mSearchText instanceof CarUiEditText) {
             ((CarUiEditText) mSearchText).registerOnPrivateImeCommandListener(
-                    new CarUiEditText.PrivateImeCommandCallback() {
-                        @Override
-                        public void onItemClicked(String itemId) {
-                            CarUiImeSearchListItem item = mIdToListItem.get(itemId);
-                            if (item != null) {
-                                CarUiContentListItem.OnClickListener listener =
-                                        item.getOnClickListener();
-                                if (listener != null) {
-                                    listener.onClick(item);
-                                }
-                            }
-                        }
-
-                        @Override
-                        public void onSecondaryImageClicked(String secondaryImageId) {
-                            CarUiImeSearchListItem item = mIdToListItem.get(secondaryImageId);
-                            if (item != null) {
-                                CarUiContentListItem.OnClickListener listener =
-                                        item.getSupplementalIconOnClickListener();
-                                if (listener != null) {
-                                    listener.onClick(item);
-                                }
-                            }
-                        }
-                    });
+                    new SearchViewImeCallback());
         }
     }
 
@@ -192,11 +184,29 @@
         searchContainer.getRootView().setOnApplyWindowInsetsListener((v, insets) -> {
             if (insets.isVisible(ime())) {
                 displaySearchWideScreen();
+                mHandler.post(() -> {
+                    if (mSurfaceControlViewHost != null && mWideScreenImeContentAreaView != null
+                            && mSurfaceControlViewHost.getView() == null) {
+                        mSurfaceControlViewHost.setView(
+                                mWideScreenImeContentAreaView, mSurfaceWidth, mSurfaceHeight);
+                    }
+                });
             }
             return insets;
         });
     }
 
+    void setViewToImeWideScreenSurface(View view) {
+        if (view == null && mSurfaceControlViewHost != null) {
+            mSurfaceControlViewHost.release();
+        }
+
+        if (view != null && view.getParent() != null) {
+            throw new IllegalStateException("view should not have a parent");
+        }
+        mWideScreenImeContentAreaView = view;
+    }
+
     private boolean isEnter(KeyEvent event) {
         boolean result = false;
         if (event != null) {
@@ -250,15 +260,24 @@
      * template.
      */
     public void setSearchItemsForWideScreen(List<? extends CarUiImeSearchListItem> searchItems) {
-        mWideScreenSearchItemList = new ArrayList<>(searchItems);
+        mWideScreenSearchItemList = searchItems != null ? new ArrayList<>(searchItems) : null;
         displaySearchWideScreen();
     }
 
     private void displaySearchWideScreen() {
         mIdToListItem.clear();
-        if (mWideScreenSearchItemList.isEmpty()) {
+        // mWideScreenImeContentAreaView will only be set when running in widescreen mode and
+        // apps allowed by OEMs are trying to set their own view. In that case we did not want to
+        // send the information to IME for templatized solution.
+        if (mWideScreenImeContentAreaView != null) {
             return;
         }
+
+        if (mWideScreenSearchItemList == null) {
+            mInputMethodManager.sendAppPrivateCommand(mSearchText, WIDE_SCREEN_ACTION, null);
+            return;
+        }
+
         ArrayList<String> itemIdList = new ArrayList<>();
         ArrayList<String> titleList = new ArrayList<>();
         ArrayList<String> subTitleList = new ArrayList<>();
@@ -357,4 +376,62 @@
         mSearchText.setText(query);
         mSearchText.setSelection(mSearchText.getText().length());
     }
+
+    private class SearchViewImeCallback implements PrivateImeCommandCallback {
+
+        @Override
+        public void onItemClicked(String itemId) {
+            CarUiImeSearchListItem item = mIdToListItem.get(itemId);
+            if (item != null) {
+                CarUiContentListItem.OnClickListener listener =
+                        item.getOnClickListener();
+                if (listener != null) {
+                    listener.onClick(item);
+                }
+            }
+        }
+
+        @Override
+        public void onSecondaryImageClicked(String secondaryImageId) {
+            CarUiImeSearchListItem item = mIdToListItem.get(secondaryImageId);
+            if (item != null) {
+                CarUiContentListItem.OnClickListener listener =
+                        item.getSupplementalIconOnClickListener();
+                if (listener != null) {
+                    listener.onClick(item);
+                }
+            }
+        }
+
+        @Override
+        public void onSurfaceInfo(int displayId, IBinder binder, int height,
+                int width) {
+            if (Build.VERSION.SDK_INT < VERSION_CODES.R
+                    || mWideScreenImeContentAreaView == null) {
+                // SurfaceControlViewHost is only available on R and above
+                return;
+            }
+
+            DisplayManager dm = (DisplayManager) getContext().getSystemService(
+                    Context.DISPLAY_SERVICE);
+
+            Display display = dm.getDisplay(displayId);
+
+            if (mSurfaceControlViewHost != null) {
+                mSurfaceControlViewHost.release();
+            }
+
+            mSurfaceControlViewHost = new SurfaceControlViewHost(getContext(),
+                    display, binder);
+
+            mSurfaceHeight = height;
+            mSurfaceWidth = width;
+
+            Bundle bundle = new Bundle();
+            bundle.putParcelable(CONTENT_AREA_SURFACE_PACKAGE,
+                    mSurfaceControlViewHost.getSurfacePackage());
+            mInputMethodManager.sendAppPrivateCommand(mSearchText,
+                    WIDE_SCREEN_ACTION, bundle);
+        }
+    }
 }
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Toolbar.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Toolbar.java
index c9a96ce..45e344d 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Toolbar.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Toolbar.java
@@ -22,6 +22,7 @@
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.View;
 import android.widget.FrameLayout;
 
 import androidx.annotation.DrawableRes;
@@ -273,6 +274,7 @@
 
     /**
      * Gets the {@link TabLayout} for this toolbar.
+     *
      * @deprecated Use other tab-related functions in the ToolbarController interface.
      */
     @Deprecated
@@ -653,13 +655,46 @@
     }
 
     /**
+     * Returns true if the toolbar can display search result items. One example of this is when the
+     * system is configured to display search items in the IME instead of in the app.
+     */
+    @Override
+    public boolean canShowSearchResultItems() {
+        return mController.canShowSearchResultItems();
+    }
+
+    /**
+     * Returns true if the app is allowed to set search results view.
+     */
+    @Override
+    public boolean canShowSearchResultsView() {
+        return mController.canShowSearchResultsView();
+    }
+
+    /**
+     * Add a view within a container that will animate with the wide screen IME to display search
+     * results.
+     *
+     * <p>Note: Apps can only call this method if the package name is allowed via OEM to render
+     * their view.  To check if the application have the permission to do so or not first call
+     * {@link #canShowSearchResultsView()}. If the app is not allowed this method will throw an
+     * {@link RuntimeException}
+     *
+     * @param view to be added in the container.
+     */
+    @Override
+    public void setSearchResultsView(View view) {
+        mController.setSearchResultsView(view);
+    }
+
+    /**
      * Sets a list of search items to be displayed in the IME window when running as a wide screen
      * mode. This should be called each time the list is updated. For example, when a user is typing
      * in the input field and the list gets filtered this method should be invoked each time.
      */
     @Override
-    public void setSearchItemsForWideScreen(List<? extends CarUiImeSearchListItem> searchItems) {
-        mController.setSearchItemsForWideScreen(searchItems);
+    public void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems) {
+        mController.setSearchResultItems(searchItems);
     }
 
     /** Registers a new {@link OnSearchCompletedListener} to the list of listeners. */
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarController.java
index 6bed46c..654fe93 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarController.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarController.java
@@ -17,6 +17,7 @@
 package com.android.car.ui.toolbar;
 
 import android.graphics.drawable.Drawable;
+import android.view.View;
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
@@ -80,6 +81,7 @@
 
     /**
      * Gets the {@link TabLayout} for this toolbar.
+     *
      * @deprecated Use other tab-related functions in this interface.
      */
     @Deprecated
@@ -277,10 +279,36 @@
     boolean unregisterOnSearchListener(Toolbar.OnSearchListener listener);
 
     /**
-     * Sets list of search item {@link CarUiListItem} to be displayed in the IMS
-     * template.
+     * Returns true if the toolbar can display search result items. One example of this is when the
+     * system is configured to display search items in the IME instead of in the app.
      */
-    void setSearchItemsForWideScreen(List<? extends CarUiImeSearchListItem> searchItems);
+    boolean canShowSearchResultItems();
+
+    /**
+     * Returns true if the app is allowed to set search results view.
+     */
+    boolean canShowSearchResultsView();
+
+    /**
+     * Add a view within a container that will animate with the wide screen IME to display search
+     * results.
+     *
+     * <p>Note: Apps can only call this method if the package name is allowed via OEM to render
+     * their view.  To check if the application have the permission to do so or not first call
+     * {@link #canShowSearchResultsView()}. If the app is not allowed this method will throw an
+     * {@link RuntimeException}
+     *
+     * @param view to be added in the container.
+     */
+    void setSearchResultsView(View view);
+
+    /**
+     * Sets list of search item {@link CarUiListItem} to be displayed in the IMS
+     * template. This method should be called when system is running in a wide screen mode. Apps
+     * can check that by using {@link #canShowSearchResultItems()}
+     * Else, this method will throw an {@link RuntimeException}
+     */
+    void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems);
 
     /** Registers a new {@link Toolbar.OnSearchCompletedListener} to the list of listeners. */
     void registerOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener);
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerImpl.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerImpl.java
index 92d57b6..e1397a4 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerImpl.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerImpl.java
@@ -21,6 +21,7 @@
 import static android.view.View.VISIBLE;
 
 import static com.android.car.ui.utils.CarUiUtils.findViewByRefId;
+import static com.android.car.ui.utils.CarUiUtils.getBooleanSystemProperty;
 import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
 
 import android.app.Activity;
@@ -51,6 +52,7 @@
 import com.android.car.ui.utils.CarUxRestrictionsUtil;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -112,6 +114,7 @@
     private AlertDialog mOverflowDialog;
     private boolean mNavIconSpaceReserved;
     private boolean mLogoFillsNavIconSpace;
+    private View mViewForContentAreaInWideScreenMode;
     private boolean mShowLogo;
     private List<? extends CarUiImeSearchListItem> mSearchItems;
     private final ProgressBarController mProgressBar;
@@ -268,6 +271,7 @@
 
     /**
      * Gets the {@link TabLayout} for this toolbar.
+     *
      * @deprecated Use other tab-related functions in the ToolbarController interface.
      */
     @Deprecated
@@ -714,6 +718,9 @@
                     ViewGroup.LayoutParams.MATCH_PARENT,
                     ViewGroup.LayoutParams.MATCH_PARENT);
             mSearchViewContainer.addView(searchView, layoutParams);
+            if (canShowSearchResultsView()) {
+                searchView.setViewToImeWideScreenSurface(mViewForContentAreaInWideScreenMode);
+            }
 
             searchView.installWindowInsetsListener(mSearchViewContainer);
 
@@ -817,13 +824,93 @@
         mOverflowButton.setVisible(showButtons && countVisibleOverflowItems() > 0);
     }
 
+    /**
+     * Return the list of package names allowed to hide the content area in wide screen IME.
+     */
+    private List<String> allowPackageList(Context context) {
+        String[] packages = context.getResources()
+                .getStringArray(R.array.car_ui_ime_wide_screen_allowed_package_list);
+        return Arrays.asList(packages);
+    }
+
+    /**
+     * Returns true if the toolbar can display search result items. One example of this is when the
+     * system is configured to display search items in the IME instead of in the app.
+     */
+    @Override
+    public boolean canShowSearchResultItems() {
+        return isWideScreenMode(mContext);
+    }
+
+    /**
+     * Returns whether or not system is running in a wide screen mode.
+     */
+    private static boolean isWideScreenMode(Context context) {
+        return getBooleanSystemProperty(context.getResources(),
+                R.string.car_ui_ime_wide_screen_system_property_name, false);
+    }
+
+    /**
+     * Returns true if the app is allowed to set search results view.
+     */
+    @Override
+    public boolean canShowSearchResultsView() {
+        boolean allowAppsToHideContentArea = mContext.getResources().getBoolean(
+                R.bool.car_ui_ime_wide_screen_allow_app_hide_content_area);
+        return isWideScreenMode(mContext) && (allowPackageList(mContext).contains(
+                mContext.getPackageName()) || allowAppsToHideContentArea);
+    }
+
+    /**
+     * Add a view within a container that will animate with the wide screen IME to display search
+     * results.
+     *
+     * <p>Note: Apps can only call this method if the package name is allowed via OEM to render
+     * their view. If the app is not allowed this method will throw an
+     * {@link IllegalAccessException}
+     *
+     * @param view to be added in the container.
+     */
+    @Override
+    public void setSearchResultsView(View view) {
+        if (!canShowSearchResultsView()) {
+            throw new RuntimeException(
+                    "not allowed to add view to wide screen IME, package name: "
+                            + mContext.getPackageName());
+        }
+
+        if (mSearchView != null) {
+            mSearchView.setViewToImeWideScreenSurface(view);
+        }
+
+        mViewForContentAreaInWideScreenMode = view;
+    }
+
+    /**
+     * Sets list of search item {@link CarUiListItem} to be displayed in the IMS
+     * template. This method should be called when system is running in a wide screen mode. Apps
+     * can check that by using {@link #canShowSearchResultItems()}
+     * Else, this method would have no effect.
+     */
+    @Override
+    public void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems) {
+        if (!canShowSearchResultItems()) {
+            throw new RuntimeException(
+                    "system not in wide screen mode, not allowed to set search result items ");
+        }
+        mSearchItems = searchItems;
+        if (mSearchView != null) {
+            mSearchView.setSearchItemsForWideScreen(searchItems);
+        }
+    }
+
+
     /** Gets the current {@link Toolbar.State} of the toolbar. */
     @Override
     public Toolbar.State getState() {
         return mState;
     }
 
-
     /**
      * Registers a new {@link Toolbar.OnHeightChangedListener} to the list of listeners. Register a
      * {@link com.android.car.ui.recyclerview.CarUiRecyclerView} only if there is a toolbar at
@@ -871,14 +958,6 @@
         return mOnSearchListeners.remove(listener);
     }
 
-    @Override
-    public void setSearchItemsForWideScreen(List<? extends CarUiImeSearchListItem> searchItems) {
-        mSearchItems = searchItems;
-        if (mSearchView != null) {
-            mSearchView.setSearchItemsForWideScreen(searchItems);
-        }
-    }
-
     /** Registers a new {@link Toolbar.OnSearchCompletedListener} to the list of listeners. */
     @Override
     public void registerOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener) {
diff --git a/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml b/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
index 43c582a..3ad5398 100644
--- a/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
@@ -16,6 +16,7 @@
 <resources>
   <overlayable name="car-ui-lib">
     <policy type="public">
+      <item type="array" name="car_ui_ime_wide_screen_allowed_package_list"/>
       <item type="attr" name="CarUiToolbarStyle"/>
       <item type="attr" name="barrierDirection"/>
       <item type="attr" name="carUiPreferenceStyle"/>
@@ -322,6 +323,7 @@
       <item type="id" name="car_ui_focus_area"/>
       <item type="id" name="car_ui_fullscreenArea"/>
       <item type="id" name="car_ui_imeWideScreenInputArea"/>
+      <item type="id" name="car_ui_ime_surface"/>
       <item type="id" name="car_ui_inputExtractActionAutomotive"/>
       <item type="id" name="car_ui_inputExtractEditTextContainer"/>
       <item type="id" name="car_ui_list_item_end_guideline"/>
@@ -450,7 +452,6 @@
       <item type="string" name="car_ui_dialog_preference_negative"/>
       <item type="string" name="car_ui_dialog_preference_positive"/>
       <item type="string" name="car_ui_ellipsis"/>
-      <item type="string" name="car_ui_ime_wide_screen_allowed_package_list"/>
       <item type="string" name="car_ui_ime_wide_screen_system_property_name"/>
       <item type="string" name="car_ui_installer_process_name"/>
       <item type="string" name="car_ui_preference_switch_off"/>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml
index f630bdc..fd7539b 100644
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml
@@ -127,10 +127,18 @@
         android:layout_height="match_parent"
         android:background="@color/car_ui_ime_wide_screen_divider_color"/>
 
+    <SurfaceView
+        android:id="@id/car_ui_ime_surface"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone"
+        android:focusable="false"/>
+
     <RelativeLayout
         android:id="@id/car_ui_contentAreaAutomotive"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:visibility="gone"
         android:background="@drawable/car_ui_ime_wide_screen_no_content_background">
         <androidx.recyclerview.widget.RecyclerView
             android:id="@id/car_ui_wideScreenSearchResultList"
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/ids.xml b/car-ui-lib/car-ui-lib/src/main/res/values/ids.xml
index 2f0b555..44a162e 100644
--- a/car-ui-lib/car-ui-lib/src/main/res/values/ids.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res/values/ids.xml
@@ -24,6 +24,7 @@
     <item type="id" name="car_ui_wideScreenInputArea"/>
     <item type="id" name="car_ui_imeWideScreenInputArea"/>
     <item type="id" name="car_ui_closeKeyboard"/>
+    <item type="id" name="car_ui_ime_surface"/>
     <item type="id" name="car_ui_fullscreenArea"/>
     <item type="id" name="car_ui_wideScreenErrorMessage"/>
     <item type="id" name="car_ui_contentAreaAutomotive"/>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values/strings.xml
index 8956411..a3f0539 100644
--- a/car-ui-lib/car-ui-lib/src/main/res/values/strings.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res/values/strings.xml
@@ -70,7 +70,8 @@
     should be separated by a ",". For example, "com.package1,com.package2,com.package3" will allow
     packages "com.package1", "com.package2" and "com.package3" to hide the content area.
     -->
-    <string name="car_ui_ime_wide_screen_allowed_package_list" translatable="false"></string>
+    <string-array name="car_ui_ime_wide_screen_allowed_package_list" translatable="false">
+    </string-array>
 
     <!-- Name of system property used to determine when wide screen mode is used. -->
     <string name="car_ui_ime_wide_screen_system_property_name" translatable="false">
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java
index e7bc6f5..1d6a27d 100644
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java
+++ b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java
@@ -66,6 +66,8 @@
  */
 public class WideScreenImeActivity extends AppCompatActivity implements InsetsChangedListener {
 
+    private static final String TAG = "WideScreenImeActivity";
+
     private final List<MenuItem> mMenuItems = new ArrayList<>();
     private final List<Pair<CharSequence, View.OnFocusChangeListener>> mEditText =
             new ArrayList<>();
@@ -125,7 +127,26 @@
         searchItems.add(item);
 
         // initial list to display in search view.
-        toolbar.setSearchItemsForWideScreen(searchItems);
+        if (toolbar.canShowSearchResultItems()) {
+            toolbar.setSearchResultItems(searchItems);
+        }
+
+        LayoutInflater inflater = LayoutInflater.from(this);
+        View contentArea = inflater.inflate(R.layout.ime_wide_screen_dummy_view, null, true);
+
+        if (toolbar.canShowSearchResultsView()) {
+            toolbar.setSearchResultsView(contentArea);
+        }
+
+        contentArea.findViewById(R.id.button_1).setOnClickListener(v ->
+                Toast.makeText(this, "Button 1 clicked", Toast.LENGTH_SHORT).show()
+        );
+
+        contentArea.findViewById(R.id.button_2).setOnClickListener(v -> {
+                    Toast.makeText(this, "Clearing the view...", Toast.LENGTH_SHORT).show();
+                    toolbar.setSearchResultsView(null);
+                }
+        );
 
         toolbar.registerOnSearchListener((query) -> {
             count[0]++;
@@ -139,7 +160,9 @@
             item1.setOnItemClickedListener(mainClickListener);
             searchItems.add(item1);
 
-            toolbar.setSearchItemsForWideScreen(searchItems);
+            if (toolbar.canShowSearchResultItems()) {
+                toolbar.setSearchResultItems(searchItems);
+            }
         });
 
         mMenuItems.add(MenuItem.builder(this)
@@ -171,7 +194,7 @@
             mSecondaryImageResId.add(R.drawable.ic_launcher);
         }
 
-        mEditText.add(Pair.create("Show IME  list view", this::showImeListView));
+        mEditText.add(Pair.create("Show IME list view", this::showImeListView));
 
         mEditText.add(Pair.create("Add icon to extracted view", this::addIconToExtractedView));
 
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml b/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml
new file mode 100644
index 0000000..1118ce9
--- /dev/null
+++ b/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2020 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.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background">
+  <Button
+      android:id="@+id/button_1"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:text="Button 1"
+      android:theme="@android:style/Theme.DeviceDefault"
+      android:textSize="@dimen/car_ui_ime_wide_screen_action_button_text_size"
+      app:layout_constraintTop_toTopOf="parent"
+      app:layout_constraintBottom_toBottomOf="parent"
+      app:layout_constraintStart_toStartOf="parent"
+      app:layout_constraintEnd_toEndOf="parent"/>
+  <Button
+      android:id="@+id/button_2"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:layout_marginTop="20dp"
+      android:text="Clear View"
+      android:theme="@android:style/Theme.DeviceDefault"
+      android:textSize="@dimen/car_ui_ime_wide_screen_action_button_text_size"
+      app:layout_constraintTop_toBottomOf="@+id/button_1"
+      app:layout_constraintStart_toStartOf="parent"
+      app:layout_constraintEnd_toEndOf="parent"/>
+</androidx.constraintlayout.widget.ConstraintLayout>
+
+
diff --git a/car-ui-lib/tests/apitest/current.xml b/car-ui-lib/tests/apitest/current.xml
index f037dbd..461ce2c 100644
--- a/car-ui-lib/tests/apitest/current.xml
+++ b/car-ui-lib/tests/apitest/current.xml
@@ -1,6 +1,7 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <!--This file is AUTO GENERATED, DO NOT EDIT MANUALLY.-->
 <resources>
+  <public type="array" name="car_ui_ime_wide_screen_allowed_package_list"/>
   <public type="attr" name="CarUiToolbarStyle"/>
   <public type="attr" name="carUiPreferenceStyle"/>
   <public type="attr" name="carUiRecyclerViewStyle"/>
@@ -257,6 +258,7 @@
   <public type="id" name="car_ui_focus_area"/>
   <public type="id" name="car_ui_fullscreenArea"/>
   <public type="id" name="car_ui_imeWideScreenInputArea"/>
+  <public type="id" name="car_ui_ime_surface"/>
   <public type="id" name="car_ui_inputExtractActionAutomotive"/>
   <public type="id" name="car_ui_inputExtractEditTextContainer"/>
   <public type="id" name="car_ui_list_item_end_guideline"/>
@@ -385,7 +387,6 @@
   <public type="string" name="car_ui_dialog_preference_negative"/>
   <public type="string" name="car_ui_dialog_preference_positive"/>
   <public type="string" name="car_ui_ellipsis"/>
-  <public type="string" name="car_ui_ime_wide_screen_allowed_package_list"/>
   <public type="string" name="car_ui_ime_wide_screen_system_property_name"/>
   <public type="string" name="car_ui_installer_process_name"/>
   <public type="string" name="car_ui_preference_switch_off"/>
diff --git a/car-ui-lib/tests/apitest/resource_utils.py b/car-ui-lib/tests/apitest/resource_utils.py
index 763c5a0..7da5642 100755
--- a/car-ui-lib/tests/apitest/resource_utils.py
+++ b/car-ui-lib/tests/apitest/resource_utils.py
@@ -108,6 +108,8 @@
 
         resName = resource.get('name')
         resType = resource.tag
+        if resType == "string-array":
+            resType = "array"
         if resource.tag == 'item' or resource.tag == 'public':
             resType = resource.get('type')