Merge Android 14 QPR2 to AOSP main

Bug: 319669529
Merged-In: I65341514f2bd3f424d6518b85cd3437ccbfd98c3
Change-Id: Ied6af35bd8e81b5c4d7aa510eb92ef8677e4bb8f
diff --git a/res/values/bools.xml b/res/values/bools.xml
new file mode 100644
index 0000000..0864ed3
--- /dev/null
+++ b/res/values/bools.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 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.
+  -->
+<resources>
+    <!-- A config determines whether to show menu item selector in toolbar menu items-->
+    <bool name="show_menu_item_selector">true</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
index 66d082f..9b5f2ac 100644
--- a/res/values/overlayable.xml
+++ b/res/values/overlayable.xml
@@ -16,6 +16,7 @@
 <resources>
   <overlayable name="CarRadio">
     <policy type="system|product|signature">
+      <item type="bool" name="show_menu_item_selector"/>
       <item type="color" name="accent_color"/>
       <item type="color" name="band_selector_flat_text_color"/>
       <item type="color" name="band_selector_flat_text_color_selected"/>
diff --git a/src/com/android/car/radio/DisplayController.java b/src/com/android/car/radio/DisplayController.java
index b2a09b5..822b34b 100644
--- a/src/com/android/car/radio/DisplayController.java
+++ b/src/com/android/car/radio/DisplayController.java
@@ -221,10 +221,9 @@
             // it's a different band - don't animate
             mChannel.setText(ProgramSelectorExt.getDisplayName(sel, 0));
         } else {
-            int fromFreq = (int) mDisplayedChannel
-                    .getFirstId(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY);
-            int toFreq = (int) sel.getFirstId(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY);
-            mChannelAnimator.setIntValues((int) fromFreq, (int) toFreq);
+            int fromFreq = (int) ProgramSelectorExt.getFrequency(mDisplayedChannel);
+            int toFreq = (int) ProgramSelectorExt.getFrequency(sel);
+            mChannelAnimator.setIntValues(fromFreq, toFreq);
             mChannelAnimator.setDuration(CHANNEL_CHANGE_DURATION_MS);
             mChannelAnimator.addUpdateListener(animation -> mChannel.setText(
                     ProgramSelectorExt.formatAmFmFrequency((int) animation.getAnimatedValue(), 0)));
diff --git a/src/com/android/car/radio/ProgramViewHolder.java b/src/com/android/car/radio/ProgramViewHolder.java
index 022c000..b84f71e 100644
--- a/src/com/android/car/radio/ProgramViewHolder.java
+++ b/src/com/android/car/radio/ProgramViewHolder.java
@@ -98,7 +98,7 @@
 
     @Override
     public void onClick(View view) {
-        mPresetClickListener.onPresetClicked(getAdapterPosition());
+        mPresetClickListener.onPresetClicked(getLayoutPosition());
     }
 
     /**
@@ -129,7 +129,7 @@
             // If there is no metadata text, then use text to indicate the favorite number to the
             // user so that list does not appear empty.
             mPresetItemMetadata.setText(mContext.getString(
-                    R.string.radio_default_favorite_metadata_text, getAdapterPosition() + 1));
+                    R.string.radio_default_favorite_metadata_text, getLayoutPosition() + 1));
         } else {
             mPresetItemMetadata.setText(programName);
         }
@@ -138,7 +138,7 @@
             boolean favoriteToggleOn =
                     ((Integer) mPresetButton.getTag() == R.drawable.ic_star_empty);
             setFavoriteButtonFilled(favoriteToggleOn);
-            mPresetFavoriteListener.onPresetFavoriteChanged(getAdapterPosition(), favoriteToggleOn);
+            mPresetFavoriteListener.onPresetFavoriteChanged(getLayoutPosition(), favoriteToggleOn);
         });
     }
 
diff --git a/src/com/android/car/radio/RadioActivity.java b/src/com/android/car/radio/RadioActivity.java
index a9da2be..f08d936 100644
--- a/src/com/android/car/radio/RadioActivity.java
+++ b/src/com/android/car/radio/RadioActivity.java
@@ -67,7 +67,7 @@
     private ToolbarController mToolbar;
     private ViewPager mViewPager;
     private RadioPagerAdapter mRadioPagerAdapter;
-
+    private boolean mShowMenuItemSelector;
     private boolean mUseSourceLogoForAppSelector;
     private MediaTrampolineHelper mMediaTrampoline;
 
@@ -104,6 +104,8 @@
                 new RadioPagerAdapter(this, getSupportFragmentManager(), mRadioController);
         mViewPager = findViewById(R.id.viewpager);
 
+        mShowMenuItemSelector =
+                getResources().getBoolean(R.bool.show_menu_item_selector);
         mUseSourceLogoForAppSelector =
                 getResources().getBoolean(R.bool.use_media_source_logo_for_app_selector);
 
@@ -236,20 +238,21 @@
                     mRadioController.switchBand(programType);
                 })
                 .build();
-
-        Intent appSelectorIntent = MediaSource.getSourceSelectorIntent(this, false);
-        MenuItem appSelectorMenuItem = MenuItem.builder(this)
-                .setIcon(mUseSourceLogoForAppSelector
-                        ? R.drawable.logo_fm_radio : R.drawable.ic_app_switch)
-                .setTinted(!mUseSourceLogoForAppSelector)
-                .setOnClickListener(m -> startActivity(appSelectorIntent))
-                .build();
-
-        ArrayList<MenuItem> menuItems = new ArrayList<>(2);
+        ArrayList<MenuItem> menuItems = new ArrayList<>();
         if (mIsConnected) {
             menuItems.add(bandSelectorMenuItem);
         }
-        menuItems.add(appSelectorMenuItem);
+
+        if (mShowMenuItemSelector) {
+            Intent appSelectorIntent = MediaSource.getSourceSelectorIntent(this, false);
+            MenuItem appSelectorMenuItem = MenuItem.builder(this)
+                    .setIcon(mUseSourceLogoForAppSelector
+                            ? R.drawable.logo_fm_radio : R.drawable.ic_app_switch)
+                    .setTinted(!mUseSourceLogoForAppSelector)
+                    .setOnClickListener(m -> startActivity(appSelectorIntent))
+                    .build();
+            menuItems.add(appSelectorMenuItem);
+        }
         mToolbar.setMenuItems(menuItems);
     }
 
diff --git a/src/com/android/car/radio/bands/ProgramType.java b/src/com/android/car/radio/bands/ProgramType.java
index 4f14ef4..47ff547 100644
--- a/src/com/android/car/radio/bands/ProgramType.java
+++ b/src/com/android/car/radio/bands/ProgramType.java
@@ -128,12 +128,14 @@
         if (!ProgramSelectorExt.isAmFmProgram(sel)) return null;
 
         // this is an AM/FM program; let's check whether it's AM or FM
-        if (!ProgramSelectorExt.hasId(sel, ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY)) {
+        if (!ProgramSelectorExt.hasId(sel, ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY)
+                && !ProgramSelectorExt.hasId(sel,
+                ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT)) {
             Log.e(TAG, "AM/FM program selector with missing frequency");
             return FM;
         }
 
-        long freq = sel.getFirstId(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY);
+        long freq = ProgramSelectorExt.getFrequency(sel);
         if (ProgramSelectorExt.isAmFrequency(freq)) return AM;
         if (ProgramSelectorExt.isFmFrequency(freq)) return FM;