diff options
| -rw-r--r-- | AndroidManifest.xml | 14 | ||||
| -rw-r--r-- | res/layout-land/radio_playback_card.xml | 12 | ||||
| -rw-r--r-- | res/layout-land/tuner_fragment.xml | 1 | ||||
| -rw-r--r-- | res/layout/browse_fragment.xml | 2 | ||||
| -rw-r--r-- | res/layout/radio_activity.xml | 17 | ||||
| -rw-r--r-- | res/layout/radio_browse_item.xml | 7 | ||||
| -rw-r--r-- | res/layout/radio_playback_card.xml | 12 | ||||
| -rw-r--r-- | res/layout/radio_playback_controls.xml | 99 | ||||
| -rw-r--r-- | res/layout/tuner_dialpad.xml | 153 | ||||
| -rw-r--r-- | res/layout/tuner_fragment.xml | 4 | ||||
| -rw-r--r-- | res/values/dimens.xml | 4 | ||||
| -rw-r--r-- | res/values/styles.xml | 8 | ||||
| -rw-r--r-- | res/values/themes.xml | 2 | ||||
| -rw-r--r-- | src/com/android/car/radio/BrowseAdapter.java | 4 | ||||
| -rw-r--r-- | src/com/android/car/radio/BrowseFragment.java | 24 | ||||
| -rw-r--r-- | src/com/android/car/radio/FavoritesFragment.java | 24 | ||||
| -rw-r--r-- | src/com/android/car/radio/ManualTunerFragment.java | 21 | ||||
| -rw-r--r-- | src/com/android/car/radio/RadioActivity.java | 28 | ||||
| -rw-r--r-- | src/com/android/car/radio/service/RadioAppServiceWrapper.java | 4 |
19 files changed, 278 insertions, 162 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 01b2412..eccbf94 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,9 +17,6 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.car.radio"> - <uses-sdk - android:minSdkVersion="25" - android:targetSdkVersion="25" /> <!-- This permission is required to allow the radio to be muted. --> <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_SETTINGS" /> @@ -30,9 +27,18 @@ <!-- Media Center permission to fetch and update the currently selected media source --> <uses-permission android:name="com.android.car.media.provider.READ_WRITE"/> + <!-- To connect to media browser services in other apps, media browser clients + that target Android 11 need to add the following in their manifest --> + <queries> + <intent> + <action android:name="android.media.browse.MediaBrowserService" /> + </intent> + </queries> + <application android:label="@string/app_name" android:icon="@drawable/logo_fm_radio" - android:theme="@style/Theme.Radio"> + android:theme="@style/Theme.Radio" + android:supportsRtl="true"> <activity android:name=".RadioActivity" diff --git a/res/layout-land/radio_playback_card.xml b/res/layout-land/radio_playback_card.xml index 622011d..39a3c22 100644 --- a/res/layout-land/radio_playback_card.xml +++ b/res/layout-land/radio_playback_card.xml @@ -19,8 +19,8 @@ limitations under the License. android:id="@+id/main_radio_display" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/playback_card_margin_horizontal" - android:layout_marginRight="@dimen/playback_card_margin_horizontal" + android:layout_marginStart="@dimen/playback_card_margin_horizontal" + android:layout_marginEnd="@dimen/playback_card_margin_horizontal" android:layout_marginBottom="@dimen/playback_card_margin_bottom" android:background="@drawable/playback_background"> @@ -40,8 +40,8 @@ limitations under the License. android:ellipsize="end" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/playback_card_interior_padding" - android:layout_marginRight="@dimen/playback_card_interior_padding" + android:layout_marginStart="@dimen/playback_card_interior_padding" + android:layout_marginEnd="@dimen/playback_card_interior_padding" android:maxLines="1" android:textAppearance="?android:attr/textAppearanceLarge" app:layout_constraintVertical_chainStyle="packed" @@ -56,8 +56,8 @@ limitations under the License. android:ellipsize="end" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/playback_card_interior_padding" - android:layout_marginRight="@dimen/playback_card_interior_padding" + android:layout_marginStart="@dimen/playback_card_interior_padding" + android:layout_marginEnd="@dimen/playback_card_interior_padding" android:paddingTop="@dimen/playback_card_text_spacing" android:maxLines="1" android:fontFamily="sans-serif-medium" diff --git a/res/layout-land/tuner_fragment.xml b/res/layout-land/tuner_fragment.xml index d90c928..65c8f29 100644 --- a/res/layout-land/tuner_fragment.xml +++ b/res/layout-land/tuner_fragment.xml @@ -46,6 +46,7 @@ limitations under the License. android:gravity="center" android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large" android:textColor="@color/manual_tuner_button_text_color" + android:textDirection="ltr" app:layout_constraintBottom_toTopOf="@+id/manual_tuner_done_button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/dialpad_layout" diff --git a/res/layout/browse_fragment.xml b/res/layout/browse_fragment.xml index 7c174b8..0cdb636 100644 --- a/res/layout/browse_fragment.xml +++ b/res/layout/browse_fragment.xml @@ -23,6 +23,6 @@ limitations under the License. android:background="@color/browse_fragment_list_color" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginLeft="@dimen/tab_margin_left" + android:layout_marginStart="@dimen/tab_margin_start" /> </LinearLayout> diff --git a/res/layout/radio_activity.xml b/res/layout/radio_activity.xml index 45c022b..bd92a9a 100644 --- a/res/layout/radio_activity.xml +++ b/res/layout/radio_activity.xml @@ -26,15 +26,6 @@ limitations under the License. android:orientation="horizontal" app:layout_constraintGuide_begin="@dimen/car_ui_toolbar_first_row_height" /> - <com.android.car.ui.toolbar.Toolbar - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:title="@string/app_name" - app:layout_constraintTop_toTopOf="parent" - app:logo="@drawable/logo_fm_radio" - app:state="home"/> - <androidx.viewpager.widget.ViewPager android:id="@+id/viewpager" android:layout_width="@dimen/radio_activity_pager_size" @@ -43,14 +34,14 @@ limitations under the License. android:layout_weight="@integer/radio_activity_view_weight" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@+id/toolbar" + app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@+id/main_radio_display" /> <TextView android:id="@+id/status_message" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@+id/toolbar" + app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@+id/main_radio_display" android:visibility="gone" style="@style/RadioStatusMessage" /> @@ -60,8 +51,8 @@ limitations under the License. android:layout_width="@dimen/radio_activity_playback_width" android:layout_height="@dimen/playback_card_height" android:layout_marginBottom="@dimen/playback_card_margin_bottom" - android:layout_marginLeft="@dimen/playback_card_margin_horizontal" - android:layout_marginRight="@dimen/playback_card_margin_horizontal" + android:layout_marginStart="@dimen/playback_card_margin_horizontal" + android:layout_marginEnd="@dimen/playback_card_margin_horizontal" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> diff --git a/res/layout/radio_browse_item.xml b/res/layout/radio_browse_item.xml index c1a256f..9bbd54b 100644 --- a/res/layout/radio_browse_item.xml +++ b/res/layout/radio_browse_item.xml @@ -50,15 +50,16 @@ limitations under the License. android:layout_gravity="center_vertical" android:layout_marginEnd="@dimen/browse_item_spacing" android:textColor="@color/browse_item_text_color" - android:textAppearance="?android:attr/textAppearanceLarge" /> + android:textAppearance="?android:attr/textAppearanceLarge" + android:textAlignment="viewStart"/> <ImageButton android:id="@+id/browse_button" android:layout_marginEnd="@dimen/browse_item_spacing" - android:layout_gravity="center_vertical|right" + android:layout_gravity="center_vertical|end" android:layout_width="@dimen/control_button_size" android:layout_height="@dimen/control_button_size" - android:gravity="right" + android:gravity="end" android:src="@drawable/ic_star_filled" style="@style/RadioButton" /> diff --git a/res/layout/radio_playback_card.xml b/res/layout/radio_playback_card.xml index 2e19fdc..f1aa4d4 100644 --- a/res/layout/radio_playback_card.xml +++ b/res/layout/radio_playback_card.xml @@ -19,8 +19,8 @@ limitations under the License. android:id="@+id/main_radio_display" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/playback_card_margin_horizontal" - android:layout_marginRight="@dimen/playback_card_margin_horizontal" + android:layout_marginStart="@dimen/playback_card_margin_horizontal" + android:layout_marginEnd="@dimen/playback_card_margin_horizontal" android:layout_marginBottom="@dimen/playback_card_margin_bottom" android:paddingTop="@dimen/playback_card_interior_padding" android:background="@drawable/playback_background"> @@ -41,8 +41,8 @@ limitations under the License. android:layout_gravity="center" android:layout_width="@dimen/playback_card_station_name_width" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/playback_card_interior_padding" - android:layout_marginRight="@dimen/playback_card_interior_padding" + android:layout_marginStart="@dimen/playback_card_interior_padding" + android:layout_marginEnd="@dimen/playback_card_interior_padding" android:maxLines="@integer/playback_card_station_name_max_lines" android:textAppearance="?android:attr/textAppearanceLarge" app:layout_constraintVertical_chainStyle="packed" @@ -59,8 +59,8 @@ limitations under the License. android:layout_width="@dimen/playback_card_station_details_width" android:layout_height="wrap_content" android:paddingTop="@dimen/playback_card_text_spacing" - android:layout_marginLeft="@dimen/playback_card_interior_padding" - android:layout_marginRight="@dimen/playback_card_interior_padding" + android:layout_marginStart="@dimen/playback_card_interior_padding" + android:layout_marginEnd="@dimen/playback_card_interior_padding" android:maxLines="@integer/playback_card_station_details_max_lines" android:textAppearance="?android:attr/textAppearanceMedium" app:layout_constraintTop_toBottomOf="@+id/station_name" diff --git a/res/layout/radio_playback_controls.xml b/res/layout/radio_playback_controls.xml index baac1cc..e3ff718 100644 --- a/res/layout/radio_playback_controls.xml +++ b/res/layout/radio_playback_controls.xml @@ -13,52 +13,65 @@ 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. --> -<LinearLayout +<!-- A dummy wrapper layout so we can set the layout direction of the LinearLayout + without impacting its positioning in a parent view group with a potentially different + layout direction. + Please note that even though most layouts mirror in RTL, playback controls should not be + mirrored as they do not refer to the direction of time. + For more details see + https://material.io/design/usability/bidirectionality.html#mirroring-elements --> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/buttons_container" android:layout_width="match_parent" - android:layout_height="@dimen/control_bar_height" - android:orientation="horizontal"> + android:layout_height="@dimen/control_bar_height"> - <ImageButton - android:id="@+id/back_button" - android:layout_gravity="center_vertical" - android:layout_width="@dimen/control_button_size" - android:layout_height="@dimen/control_button_size" - android:layout_weight="@integer/playback_controls_back_button_weight" - android:src="@drawable/ic_skip_previous" - android:background="@drawable/playback_button_background" - style="@style/RadioButton" /> + <LinearLayout + android:id="@+id/buttons_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:layoutDirection="ltr"> - <com.android.car.radio.widget.PlayPauseButton - android:id="@+id/play_button" - android:layout_gravity="center_vertical" - android:layout_width="@dimen/control_button_size" - android:layout_height="@dimen/control_button_size" - android:layout_weight="@integer/playback_controls_play_button_weight" - android:stateListAnimator="@anim/fab_state_list_animator" - android:src="@drawable/ic_play_pause_stop" - android:scaleType="center" - android:background="@drawable/playback_button_background" - android:tint="@color/playback_controls_play_button_color"/> + <ImageButton + android:id="@+id/back_button" + android:layout_gravity="center_vertical" + android:layout_width="@dimen/control_button_size" + android:layout_height="@dimen/control_button_size" + android:layout_weight="@integer/playback_controls_back_button_weight" + android:src="@drawable/ic_skip_previous" + android:background="@drawable/playback_button_background" + style="@style/RadioButton" /> - <ImageButton - android:id="@+id/forward_button" - android:layout_gravity="center_vertical" - android:layout_width="@dimen/control_button_size" - android:layout_height="@dimen/control_button_size" - android:layout_weight="@integer/playback_controls_forward_button_weight" - android:src="@drawable/ic_skip_next" - android:background="@drawable/playback_button_background" - style="@style/RadioButton" /> + <com.android.car.radio.widget.PlayPauseButton + android:id="@+id/play_button" + android:layout_gravity="center_vertical" + android:layout_width="@dimen/control_button_size" + android:layout_height="@dimen/control_button_size" + android:layout_weight="@integer/playback_controls_play_button_weight" + android:stateListAnimator="@anim/fab_state_list_animator" + android:src="@drawable/ic_play_pause_stop" + android:scaleType="center" + android:background="@drawable/playback_button_background" + android:tint="@color/playback_controls_play_button_color"/> - <ImageButton - android:id="@+id/add_presets_button" - android:layout_gravity="center_vertical" - android:layout_width="@dimen/control_button_size" - android:layout_height="@dimen/control_button_size" - android:layout_weight="@integer/playback_controls_presets_button_weight" - android:src="@drawable/ic_star_empty" - android:background="@drawable/playback_button_background" - style="@style/RadioButton" /> -</LinearLayout>
\ No newline at end of file + <ImageButton + android:id="@+id/forward_button" + android:layout_gravity="center_vertical" + android:layout_width="@dimen/control_button_size" + android:layout_height="@dimen/control_button_size" + android:layout_weight="@integer/playback_controls_forward_button_weight" + android:src="@drawable/ic_skip_next" + android:background="@drawable/playback_button_background" + style="@style/RadioButton" /> + + <ImageButton + android:id="@+id/add_presets_button" + android:layout_gravity="center_vertical" + android:layout_width="@dimen/control_button_size" + android:layout_height="@dimen/control_button_size" + android:layout_weight="@integer/playback_controls_presets_button_weight" + android:src="@drawable/ic_star_empty" + android:background="@drawable/playback_button_background" + style="@style/RadioButton" /> + </LinearLayout> +</FrameLayout> diff --git a/res/layout/tuner_dialpad.xml b/res/layout/tuner_dialpad.xml index 57a572a..506940b 100644 --- a/res/layout/tuner_dialpad.xml +++ b/res/layout/tuner_dialpad.xml @@ -13,79 +13,88 @@ 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. --> -<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:columnCount="@integer/tuner_dialpad_column_count"> +<!-- A dummy wrapper layout so we can set the layout direction of the GridLayout + without impacting its positioning in a parent view group with a potentially different + layout direction. --> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <!-- Dialpad should always have LTR layout regardless of the locale. --> + <GridLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:columnCount="@integer/tuner_dialpad_column_count" + android:layoutDirection="ltr"> - <!-- Row 1 --> - <Button - android:id="@+id/manual_tuner_1" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:text="@string/manual_tuner_1" - android:tag="1" - style="@style/DialpadKeyButtonStyle" /> - <Button - android:id="@+id/manual_tuner_2" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:text="@string/manual_tuner_2" - android:tag="2" - style="@style/DialpadKeyButtonStyle" /> - <Button - android:id="@+id/manual_tuner_3" - android:text="@string/manual_tuner_3" - android:tag="3" - style="@style/DialpadKeyButtonStyle" /> + <!-- Row 1 --> + <Button + android:id="@+id/manual_tuner_1" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:text="1" + android:tag="1" + style="@style/DialpadKeyButtonStyle" /> + <Button + android:id="@+id/manual_tuner_2" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:text="@string/manual_tuner_2" + android:tag="2" + style="@style/DialpadKeyButtonStyle" /> + <Button + android:id="@+id/manual_tuner_3" + android:text="@string/manual_tuner_3" + android:tag="3" + style="@style/DialpadKeyButtonStyle" /> - <!-- Row 2 --> - <Button - android:id="@+id/manual_tuner_4" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:text="@string/manual_tuner_4" - android:tag="4" - style="@style/DialpadKeyButtonStyle" /> - <Button - android:id="@+id/manual_tuner_5" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:text="@string/manual_tuner_5" - android:tag="5" - style="@style/DialpadKeyButtonStyle" /> - <Button - android:id="@+id/manual_tuner_6" - android:text="@string/manual_tuner_6" - android:tag="6" - style="@style/DialpadKeyButtonStyle" /> + <!-- Row 2 --> + <Button + android:id="@+id/manual_tuner_4" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:text="@string/manual_tuner_4" + android:tag="4" + style="@style/DialpadKeyButtonStyle" /> + <Button + android:id="@+id/manual_tuner_5" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:text="@string/manual_tuner_5" + android:tag="5" + style="@style/DialpadKeyButtonStyle" /> + <Button + android:id="@+id/manual_tuner_6" + android:text="@string/manual_tuner_6" + android:tag="6" + style="@style/DialpadKeyButtonStyle" /> - <!-- Row 3 --> - <Button - android:id="@+id/manual_tuner_7" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:text="@string/manual_tuner_7" - android:tag="7" - style="@style/DialpadKeyButtonStyle" /> - <Button - android:id="@+id/manual_tuner_8" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:text="@string/manual_tuner_8" - android:tag="8" - style="@style/DialpadKeyButtonStyle" /> - <Button - android:id="@+id/manual_tuner_9" - android:text="@string/manual_tuner_9" - android:tag="9" - style="@style/DialpadKeyButtonStyle" /> + <!-- Row 3 --> + <Button + android:id="@+id/manual_tuner_7" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:text="@string/manual_tuner_7" + android:tag="7" + style="@style/DialpadKeyButtonStyle" /> + <Button + android:id="@+id/manual_tuner_8" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:text="@string/manual_tuner_8" + android:tag="8" + style="@style/DialpadKeyButtonStyle" /> + <Button + android:id="@+id/manual_tuner_9" + android:text="@string/manual_tuner_9" + android:tag="9" + style="@style/DialpadKeyButtonStyle"/> - <!-- Row 4 --> - <ImageView - android:id="@+id/manual_tuner_backspace" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:scaleType="center" - android:src="@drawable/ic_backspace" - style="@style/DialpadKeyButtonStyle" /> - <Button - android:id="@+id/manual_tuner_0" - android:layout_marginRight="@dimen/dialpad_space_horizontal" - android:text="@string/manual_tuner_0" - android:tag="0" - style="@style/DialpadKeyButtonStyle" /> -</GridLayout>
\ No newline at end of file + <!-- Row 4 --> + <ImageView + android:id="@+id/manual_tuner_backspace" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:scaleType="center" + android:src="@drawable/ic_backspace" + style="@style/DialpadKeyButtonStyle" /> + <Button + android:id="@+id/manual_tuner_0" + android:layout_marginRight="@dimen/dialpad_space_horizontal" + android:text="@string/manual_tuner_0" + android:tag="0" + style="@style/DialpadKeyButtonStyle" /> + </GridLayout> +</FrameLayout>
\ No newline at end of file diff --git a/res/layout/tuner_fragment.xml b/res/layout/tuner_fragment.xml index 3bdb097..458dd22 100644 --- a/res/layout/tuner_fragment.xml +++ b/res/layout/tuner_fragment.xml @@ -20,6 +20,9 @@ limitations under the License. android:layout_width="match_parent" android:layout_height="match_parent"> + <!-- Using LTR text direction since this textView displays bidi strings that should always have + LTR direction. Otherwise, the period character in "123." would be interpreted as end of + the sentence. This results in ".123" in RTL text direction which is not what we want. --> <TextView android:id="@+id/manual_tuner_channel" android:layout_width="wrap_content" @@ -27,6 +30,7 @@ limitations under the License. android:gravity="center" android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large" android:textColor="@color/manual_tuner_button_text_color" + android:textDirection="ltr" app:layout_constraintBottom_toTopOf="@+id/dialpad_layout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 8edd032..3d60272 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -103,8 +103,8 @@ limitations under the License. <dimen name="tab_icon_margin">@*android:dimen/car_padding_1</dimen> <dimen name="tab_elevation">8dp</dimen> <dimen name="tab_padding">@*android:dimen/car_padding_4</dimen> - <dimen name="tab_margin_left">@*android:dimen/car_padding_4</dimen> - <dimen name="tab_margin_right">@dimen/radio_margin</dimen> + <dimen name="tab_margin_start">@*android:dimen/car_padding_4</dimen> + <dimen name="tab_margin_end">@dimen/radio_margin</dimen> <dimen name="band_selector_size">@dimen/tab_height</dimen> </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml index 635a19f..20001dc 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -18,6 +18,10 @@ limitations under the License. <style name="RadioButton"> <item name="android:background">?android:attr/selectableItemBackground</item> <item name="android:padding">@dimen/radio_controls_button_padding</item> + <!-- Added paddingStart/End explicitly since padding does not override paddingStart/End + when RTL support is enabled --> + <item name="android:paddingStart">@dimen/radio_controls_button_padding</item> + <item name="android:paddingEnd">@dimen/radio_controls_button_padding</item> <item name="android:scaleType">center</item> </style> @@ -27,6 +31,10 @@ limitations under the License. <item name="android:layout_height">@dimen/dialpad_button_size</item> <item name="android:layout_marginBottom">@dimen/dialpad_space_vertical</item> <item name="android:padding">@dimen/dialpad_button_padding</item> + <!-- Added paddingStart/End explicitly since padding does not override paddingStart/End + when RTL support is enabled --> + <item name="android:paddingStart">@dimen/dialpad_button_padding</item> + <item name="android:paddingEnd">@dimen/dialpad_button_padding</item> <item name="android:gravity">center</item> <item name="android:layout_gravity">center</item> <item name="android:background">?android:attr/selectableItemBackground</item> diff --git a/res/values/themes.xml b/res/values/themes.xml index 1c88003..90fdf5d 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -15,7 +15,7 @@ limitations under the License. --> <resources> <!--Theme for the app. --> - <style name="Theme.Radio" parent="android:Theme.DeviceDefault.NoActionBar"> + <style name="Theme.Radio" parent="Theme.CarUi.WithToolbar"> <item name="textAppearanceGridItem">@android:style/TextAppearance.DeviceDefault.Medium</item> <item name="textAppearanceGridItemSecondary">@android:style/TextAppearance.DeviceDefault.Small</item> </style> diff --git a/src/com/android/car/radio/BrowseAdapter.java b/src/com/android/car/radio/BrowseAdapter.java index b894b55..2ca2376 100644 --- a/src/com/android/car/radio/BrowseAdapter.java +++ b/src/com/android/car/radio/BrowseAdapter.java @@ -238,7 +238,7 @@ public class BrowseAdapter extends RecyclerView.Adapter<ProgramViewHolder> { private void handlePresetClicked(int position) { synchronized (mLock) { if (mItemClickListener == null) return; - if (position >= getItemCount()) return; + if (position < 0 || position >= getItemCount()) return; mItemClickListener.onItemClicked(getEntryLocked(position).program.getSelector()); } @@ -247,7 +247,7 @@ public class BrowseAdapter extends RecyclerView.Adapter<ProgramViewHolder> { private void handlePresetFavoriteChanged(int position, boolean saveAsFavorite) { synchronized (mLock) { if (mItemFavoriteListener == null) return; - if (position >= getItemCount()) return; + if (position < 0 || position >= getItemCount()) return; mItemFavoriteListener.onItemFavoriteChanged( getEntryLocked(position).program, saveAsFavorite); diff --git a/src/com/android/car/radio/BrowseFragment.java b/src/com/android/car/radio/BrowseFragment.java index 4661df3..f81fc1d 100644 --- a/src/com/android/car/radio/BrowseFragment.java +++ b/src/com/android/car/radio/BrowseFragment.java @@ -16,6 +16,8 @@ package com.android.car.radio; +import static com.android.car.ui.core.CarUi.requireInsets; + import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; @@ -28,11 +30,13 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.car.broadcastradio.support.Program; import com.android.car.radio.storage.RadioStorage; +import com.android.car.ui.baselayout.Insets; +import com.android.car.ui.baselayout.InsetsChangedListener; /** * Fragment that shows all browseable radio stations from background scan */ -public class BrowseFragment extends Fragment { +public class BrowseFragment extends Fragment implements InsetsChangedListener { private RadioController mRadioController; private BrowseAdapter mBrowseAdapter; @@ -76,6 +80,24 @@ public class BrowseFragment extends Fragment { } } + @Override + public void onCarUiInsetsChanged(Insets insets) { + View view = requireView(); + View recyclerView = view.findViewById(R.id.browse_list); + recyclerView.setPadding(insets.getLeft(), + insets.getTop(), + insets.getRight(), + insets.getBottom()); + } + + @Override + public void onStart() { + super.onStart(); + + // This is needed to apply the inset changes that happened before this fragment was visible + onCarUiInsetsChanged(requireInsets(getActivity())); + } + private void handlePresetItemFavoriteChanged(Program program, boolean saveAsFavorite) { if (saveAsFavorite) { mRadioStorage.addFavorite(program); diff --git a/src/com/android/car/radio/FavoritesFragment.java b/src/com/android/car/radio/FavoritesFragment.java index 3154dba..218a318 100644 --- a/src/com/android/car/radio/FavoritesFragment.java +++ b/src/com/android/car/radio/FavoritesFragment.java @@ -16,6 +16,8 @@ package com.android.car.radio; +import static com.android.car.ui.core.CarUi.requireInsets; + import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; @@ -28,11 +30,13 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.car.broadcastradio.support.Program; import com.android.car.radio.storage.RadioStorage; +import com.android.car.ui.baselayout.Insets; +import com.android.car.ui.baselayout.InsetsChangedListener; /** * Fragment that shows a list of all the current favorite radio stations */ -public class FavoritesFragment extends Fragment { +public class FavoritesFragment extends Fragment implements InsetsChangedListener { private RadioController mRadioController; private BrowseAdapter mBrowseAdapter; @@ -76,6 +80,24 @@ public class FavoritesFragment extends Fragment { } } + @Override + public void onCarUiInsetsChanged(Insets insets) { + View view = requireView(); + View recyclerView = view.findViewById(R.id.browse_list); + recyclerView.setPadding(insets.getLeft(), + insets.getTop(), + insets.getRight(), + insets.getBottom()); + } + + @Override + public void onStart() { + super.onStart(); + + // This is needed to apply the inset changes that happened before this fragment was visible + onCarUiInsetsChanged(requireInsets(getActivity())); + } + private void handlePresetItemFavoriteChanged(Program program, boolean saveAsFavorite) { if (saveAsFavorite) { mRadioStorage.addFavorite(program); diff --git a/src/com/android/car/radio/ManualTunerFragment.java b/src/com/android/car/radio/ManualTunerFragment.java index 737edb9..9fe6bcc 100644 --- a/src/com/android/car/radio/ManualTunerFragment.java +++ b/src/com/android/car/radio/ManualTunerFragment.java @@ -16,6 +16,8 @@ package com.android.car.radio; +import static com.android.car.ui.core.CarUi.requireInsets; + import android.hardware.radio.RadioManager.ProgramInfo; import android.os.Bundle; import android.view.LayoutInflater; @@ -25,11 +27,13 @@ import android.view.ViewGroup; import androidx.fragment.app.Fragment; import com.android.car.radio.bands.ProgramType; +import com.android.car.ui.baselayout.Insets; +import com.android.car.ui.baselayout.InsetsChangedListener; /** * Fragment that allows tuning to a specific frequency using a keypad */ -public class ManualTunerFragment extends Fragment { +public class ManualTunerFragment extends Fragment implements InsetsChangedListener { private ManualTunerController mController; private RadioController mRadioController; @@ -57,6 +61,21 @@ public class ManualTunerFragment extends Fragment { } } + @Override + public void onCarUiInsetsChanged(Insets insets) { + View view = requireView(); + view.setPadding(insets.getLeft(), insets.getTop(), + insets.getRight(), insets.getBottom()); + } + + @Override + public void onStart() { + super.onStart(); + + // This is needed to apply the inset changes that happened before this fragment was visible + onCarUiInsetsChanged(requireInsets(getActivity())); + } + static ManualTunerFragment newInstance(RadioController radioController) { ManualTunerFragment fragment = new ManualTunerFragment(); fragment.mRadioController = radioController; diff --git a/src/com/android/car/radio/RadioActivity.java b/src/com/android/car/radio/RadioActivity.java index a9a956a..73582b5 100644 --- a/src/com/android/car/radio/RadioActivity.java +++ b/src/com/android/car/radio/RadioActivity.java @@ -16,6 +16,11 @@ package com.android.car.radio; +import static android.car.media.CarMediaManager.MEDIA_SOURCE_MODE_BROWSE; + +import static com.android.car.ui.core.CarUi.requireToolbar; +import static com.android.car.ui.toolbar.Toolbar.State.HOME; + import android.car.Car; import android.content.Intent; import android.graphics.drawable.Drawable; @@ -30,9 +35,11 @@ import com.android.car.media.common.source.MediaSource; import com.android.car.media.common.source.MediaSourceViewModel; import com.android.car.radio.bands.ProgramType; import com.android.car.radio.util.Log; +import com.android.car.ui.baselayout.Insets; +import com.android.car.ui.baselayout.InsetsChangedListener; import com.android.car.ui.toolbar.MenuItem; import com.android.car.ui.toolbar.TabLayout; -import com.android.car.ui.toolbar.Toolbar; +import com.android.car.ui.toolbar.ToolbarController; import java.util.Arrays; import java.util.List; @@ -40,7 +47,7 @@ import java.util.List; /** * The main activity for the radio app. */ -public class RadioActivity extends FragmentActivity { +public class RadioActivity extends FragmentActivity implements InsetsChangedListener { private static final String TAG = "BcRadioApp.activity"; /** @@ -57,10 +64,17 @@ public class RadioActivity extends FragmentActivity { private RadioController mRadioController; private BandController mBandController = new BandController(); - private Toolbar mToolbar; + private ToolbarController mToolbar; private RadioPagerAdapter mRadioPagerAdapter; @Override + public void onCarUiInsetsChanged(Insets insets) { + // This InsetsChangedListener is just a marker that we will later handle + // insets in fragments, since the fragments aren't added immediately. + // Otherwise CarUi will apply the insets to the content view incorrectly. + } + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -82,14 +96,18 @@ public class RadioActivity extends FragmentActivity { ViewPager viewPager = findViewById(R.id.viewpager); viewPager.setAdapter(mRadioPagerAdapter); - mToolbar = requireViewById(R.id.toolbar); + mToolbar = requireToolbar(this); + mToolbar.setState(HOME); + mToolbar.setTitle(R.string.app_name); + mToolbar.setLogo(R.drawable.logo_fm_radio); mToolbar.registerOnTabSelectedListener(t -> viewPager.setCurrentItem(mToolbar.getTabLayout().getTabPosition(t))); updateMenuItems(); setupTabsWithViewPager(viewPager); - MediaSourceViewModel model = MediaSourceViewModel.get(getApplication()); + MediaSourceViewModel model = + MediaSourceViewModel.get(getApplication(), MEDIA_SOURCE_MODE_BROWSE); model.getPrimaryMediaSource().observe(this, source -> { if (source != null) { // Always go through the trampoline activity to keep all the dispatching logic diff --git a/src/com/android/car/radio/service/RadioAppServiceWrapper.java b/src/com/android/car/radio/service/RadioAppServiceWrapper.java index 0ab882d..154a408 100644 --- a/src/com/android/car/radio/service/RadioAppServiceWrapper.java +++ b/src/com/android/car/radio/service/RadioAppServiceWrapper.java @@ -202,7 +202,9 @@ public class RadioAppServiceWrapper { throw new IllegalStateException( "This is not a remote service wrapper, you can't unbind it"); } - callService(service -> service.removeCallback(mCallback)); + try { + callService(service -> service.removeCallback(mCallback)); + } catch (IllegalStateException e) { } // it's fine if the service is not connected mClientContext.unbindService(mServiceConnection); } |
